@jungjaehoon/mama-server 1.11.0 β 1.11.1
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 +1 -1
- package/src/server.js +65 -263
package/package.json
CHANGED
package/src/server.js
CHANGED
|
@@ -192,272 +192,79 @@ class MAMAServer {
|
|
|
192
192
|
}
|
|
193
193
|
|
|
194
194
|
setupHandlers() {
|
|
195
|
-
//
|
|
196
|
-
//
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
2. Check if same topic exists (yours will supersede it)
|
|
214
|
-
3. MUST include link in reasoning/summary field
|
|
215
|
-
|
|
216
|
-
π LINKING FORMAT:
|
|
217
|
-
β’ [Decision] reasoning: End with 'builds_on: <id>' or 'debates: <id>' or 'synthesizes: [id1, id2]'
|
|
218
|
-
β’ [Checkpoint] summary: Include 'Related decisions: decision_xxx, decision_yyy'
|
|
219
|
-
|
|
220
|
-
type='decision': choices & lessons (same topic = evolution chain)
|
|
221
|
-
type='checkpoint': session state for resumption (ALSO requires search first!)`,
|
|
222
|
-
inputSchema: {
|
|
223
|
-
type: 'object',
|
|
224
|
-
properties: {
|
|
225
|
-
type: {
|
|
226
|
-
type: 'string',
|
|
227
|
-
enum: ['decision', 'checkpoint'],
|
|
228
|
-
description: "What to save: 'decision' or 'checkpoint'",
|
|
229
|
-
},
|
|
230
|
-
// Decision fields
|
|
231
|
-
topic: {
|
|
232
|
-
type: 'string',
|
|
233
|
-
description:
|
|
234
|
-
"[Decision] Topic identifier (e.g., 'auth_strategy'). β‘ REUSE same topic = supersedes previous, creating evolution chain.",
|
|
235
|
-
},
|
|
236
|
-
decision: {
|
|
237
|
-
type: 'string',
|
|
238
|
-
description: "[Decision] The decision made (e.g., 'Use JWT with refresh tokens').",
|
|
239
|
-
},
|
|
240
|
-
reasoning: {
|
|
241
|
-
type: 'string',
|
|
242
|
-
description:
|
|
243
|
-
"[Decision] Why this decision was made. Include 5-layer narrative: (1) Context - what problem/situation; (2) Evidence - what proves this works (tests, benchmarks, prior experience); (3) Alternatives - what other options were considered and why rejected; (4) Risks - known limitations or failure modes; (5) Rationale - final reasoning for this choice. β οΈ REQUIRED: End with 'builds_on: <id>' or 'debates: <id>' or 'synthesizes: [id1, id2]' to link related decisions.",
|
|
244
|
-
},
|
|
245
|
-
confidence: {
|
|
246
|
-
type: 'number',
|
|
247
|
-
description: '[Decision] Confidence 0.0-1.0. Default: 0.5',
|
|
248
|
-
minimum: 0,
|
|
249
|
-
maximum: 1,
|
|
250
|
-
},
|
|
251
|
-
// Scope & temporal fields
|
|
252
|
-
scopes: {
|
|
253
|
-
type: 'array',
|
|
254
|
-
items: {
|
|
255
|
-
type: 'object',
|
|
256
|
-
properties: {
|
|
257
|
-
kind: {
|
|
258
|
-
type: 'string',
|
|
259
|
-
enum: ['global', 'user', 'channel', 'project'],
|
|
260
|
-
},
|
|
261
|
-
id: { type: 'string' },
|
|
262
|
-
},
|
|
263
|
-
required: ['kind', 'id'],
|
|
264
|
-
},
|
|
265
|
-
description:
|
|
266
|
-
'[Decision] Memory scopes for isolation. Example: [{"kind": "project", "id": "/path/to/project"}]',
|
|
267
|
-
},
|
|
268
|
-
event_date: {
|
|
269
|
-
type: 'string',
|
|
270
|
-
description:
|
|
271
|
-
'[Decision] ISO 8601 date when the event occurred (e.g., "2024-01-15"). Defaults to now.',
|
|
272
|
-
},
|
|
273
|
-
// Checkpoint fields
|
|
274
|
-
summary: {
|
|
275
|
-
type: 'string',
|
|
276
|
-
description:
|
|
277
|
-
"[Checkpoint] Session state summary. Use 4-section format: (1) π― Goal & Progress - what was the goal, where did you stop; (2) β
Evidence - mark each item as Verified/Not run/Assumed with proof; (3) β³ Unfinished & Risks - incomplete work, blockers, unknowns; (4) π¦ Next Agent Briefing - Definition of Done, quick health checks to run first. β οΈ Include 'Related decisions: decision_xxx, decision_yyy' to link context.",
|
|
278
|
-
},
|
|
279
|
-
next_steps: {
|
|
280
|
-
type: 'string',
|
|
281
|
-
description:
|
|
282
|
-
'[Checkpoint] Instructions for next session: DoD (Definition of Done), quick verification commands (npm test, curl health), constraints/cautions.',
|
|
283
|
-
},
|
|
284
|
-
open_files: {
|
|
285
|
-
type: 'array',
|
|
286
|
-
items: { type: 'string' },
|
|
287
|
-
description: '[Checkpoint] Currently relevant files.',
|
|
288
|
-
},
|
|
195
|
+
// Tool definitions come from src/tools/ (single source of truth).
|
|
196
|
+
// Legacy unified tools (save, search, update) kept as wrappers for backward compat.
|
|
197
|
+
const legacyNotice = this.legacyHttpEmbeddingMode
|
|
198
|
+
? `${this.getLegacyMigrationNotice()}\n\n`
|
|
199
|
+
: '';
|
|
200
|
+
|
|
201
|
+
const legacyTools = [
|
|
202
|
+
{
|
|
203
|
+
name: 'save',
|
|
204
|
+
description: `${legacyNotice}${memoryTools.save_decision.description}\n\nAlso supports type='checkpoint' for session state.`,
|
|
205
|
+
inputSchema: {
|
|
206
|
+
type: 'object',
|
|
207
|
+
properties: {
|
|
208
|
+
...memoryTools.save_decision.inputSchema.properties,
|
|
209
|
+
type: {
|
|
210
|
+
type: 'string',
|
|
211
|
+
enum: ['decision', 'checkpoint'],
|
|
212
|
+
description: "What to save: 'decision' or 'checkpoint'",
|
|
289
213
|
},
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
// 2. SEARCH - Unified search across decisions and checkpoints
|
|
294
|
-
{
|
|
295
|
-
name: 'search',
|
|
296
|
-
description: `π Search the reasoning graph before acting.
|
|
297
|
-
|
|
298
|
-
β‘ TRIGGERS - Call this BEFORE:
|
|
299
|
-
β’ β οΈ REQUIRED before 'save' (find links first!)
|
|
300
|
-
β’ Making architectural choices (check prior art)
|
|
301
|
-
β’ Debugging (find past failures on similar issues)
|
|
302
|
-
β’ Starting work on a topic (load context)
|
|
303
|
-
β’ User asks: "λμλλΌ", "what did we decide", "μ΄μ μ"
|
|
304
|
-
|
|
305
|
-
π USE FOR REASONING GRAPH:
|
|
306
|
-
β’ Find decisions to supersede (same topic)
|
|
307
|
-
β’ Find decisions to link (builds_on, debates, synthesizes)
|
|
308
|
-
β’ Understand decision evolution (time-ordered results)
|
|
309
|
-
|
|
310
|
-
Cross-lingual: Works in Korean and English.
|
|
311
|
-
β οΈ High similarity (>0.8) = MUST link with builds_on/debates/synthesizes.
|
|
312
|
-
|
|
313
|
-
π§ OUTPUT EXPECTATION:
|
|
314
|
-
When presenting search results to the user or agent, include a brief **Reasoning Summary** grounded in the actual results:
|
|
315
|
-
- Why these results match (tokens/endpoint/field overlap)
|
|
316
|
-
- What is known vs unknown (explicitly mark unknowns)
|
|
317
|
-
- What to do next (use contract fields, avoid guessing)`,
|
|
318
|
-
inputSchema: {
|
|
319
|
-
type: 'object',
|
|
320
|
-
properties: {
|
|
321
|
-
query: {
|
|
322
|
-
type: 'string',
|
|
323
|
-
description:
|
|
324
|
-
'Search query (optional). Semantic search finds related decisions even with different wording. If empty, returns recent items sorted by time.',
|
|
325
|
-
},
|
|
326
|
-
type: {
|
|
327
|
-
type: 'string',
|
|
328
|
-
enum: ['all', 'decision', 'checkpoint'],
|
|
329
|
-
description:
|
|
330
|
-
"Filter by type: 'decision' for architectural choices, 'checkpoint' for session states, 'all' for both. Default: 'all'",
|
|
331
|
-
},
|
|
332
|
-
limit: {
|
|
333
|
-
type: 'number',
|
|
334
|
-
description: 'Maximum results. Default: 10',
|
|
335
|
-
},
|
|
336
|
-
scopes: {
|
|
337
|
-
type: 'array',
|
|
338
|
-
items: {
|
|
339
|
-
type: 'object',
|
|
340
|
-
properties: {
|
|
341
|
-
kind: {
|
|
342
|
-
type: 'string',
|
|
343
|
-
enum: ['global', 'user', 'channel', 'project'],
|
|
344
|
-
},
|
|
345
|
-
id: { type: 'string' },
|
|
346
|
-
},
|
|
347
|
-
required: ['kind', 'id'],
|
|
348
|
-
},
|
|
349
|
-
description: 'Filter search results by scope.',
|
|
350
|
-
},
|
|
214
|
+
summary: {
|
|
215
|
+
type: 'string',
|
|
216
|
+
description: '[Checkpoint] Session state summary.',
|
|
351
217
|
},
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
{
|
|
356
|
-
name: 'update',
|
|
357
|
-
description: `π Update decision outcome after real-world validation.
|
|
358
|
-
|
|
359
|
-
β‘ TRIGGERS - Call this when:
|
|
360
|
-
β’ Days/weeks later: issues discovered β mark 'failed' + reason
|
|
361
|
-
β’ Production success confirmed β mark 'success'
|
|
362
|
-
β’ Partial results with caveats β mark 'partial'
|
|
363
|
-
β’ User says: "μ΄κ±° μλμ΄", "this didn't work", "μ±κ³΅νμ΄"
|
|
364
|
-
|
|
365
|
-
π REASONING GRAPH IMPACT:
|
|
366
|
-
β’ 'failed' outcomes teach future LLMs what to avoid
|
|
367
|
-
β’ After failure β save NEW decision with same topic to supersede
|
|
368
|
-
|
|
369
|
-
π‘ TIP: Don't just update - if approach changed, save a NEW decision with same topic. This creates evolution history.`,
|
|
370
|
-
inputSchema: {
|
|
371
|
-
type: 'object',
|
|
372
|
-
properties: {
|
|
373
|
-
id: {
|
|
374
|
-
type: 'string',
|
|
375
|
-
description: 'Decision ID to update.',
|
|
376
|
-
},
|
|
377
|
-
outcome: {
|
|
378
|
-
type: 'string',
|
|
379
|
-
description:
|
|
380
|
-
"New outcome status (case-insensitive): 'success' or 'SUCCESS', 'failed' or 'FAILED', 'partial' or 'PARTIAL'.",
|
|
381
|
-
},
|
|
382
|
-
reason: {
|
|
383
|
-
type: 'string',
|
|
384
|
-
description:
|
|
385
|
-
'Why it succeeded/failed/was partial. Include specific evidence: error logs, metrics, user feedback, or what broke.',
|
|
386
|
-
},
|
|
218
|
+
next_steps: {
|
|
219
|
+
type: 'string',
|
|
220
|
+
description: '[Checkpoint] Instructions for next session.',
|
|
387
221
|
},
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
{
|
|
393
|
-
name: 'search_decisions_and_contracts',
|
|
394
|
-
description:
|
|
395
|
-
'Search decisions and related contracts for PreToolUse injection (MAMA v2 hooks).',
|
|
396
|
-
inputSchema: {
|
|
397
|
-
type: 'object',
|
|
398
|
-
properties: {
|
|
399
|
-
query: {
|
|
400
|
-
type: 'string',
|
|
401
|
-
description: 'Search query for decisions.',
|
|
402
|
-
},
|
|
403
|
-
filePath: {
|
|
404
|
-
type: 'string',
|
|
405
|
-
description: 'File path context for contract search.',
|
|
406
|
-
},
|
|
407
|
-
toolName: {
|
|
408
|
-
type: 'string',
|
|
409
|
-
description: 'Tool name context (Edit/Write/apply_patch).',
|
|
410
|
-
},
|
|
411
|
-
decisionLimit: {
|
|
412
|
-
type: 'number',
|
|
413
|
-
description: 'Max decision results (default: 5).',
|
|
414
|
-
},
|
|
415
|
-
contractLimit: {
|
|
416
|
-
type: 'number',
|
|
417
|
-
description: 'Max contract results (default: 3).',
|
|
418
|
-
},
|
|
419
|
-
similarityThreshold: {
|
|
420
|
-
type: 'number',
|
|
421
|
-
description: 'Similarity threshold for vector search (default: 0.7).',
|
|
422
|
-
},
|
|
222
|
+
open_files: {
|
|
223
|
+
type: 'array',
|
|
224
|
+
items: { type: 'string' },
|
|
225
|
+
description: '[Checkpoint] Currently relevant files.',
|
|
423
226
|
},
|
|
424
227
|
},
|
|
228
|
+
required: ['type'],
|
|
425
229
|
},
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
inputSchema: {
|
|
445
|
-
type: 'object',
|
|
446
|
-
properties: {},
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
name: 'search',
|
|
233
|
+
description: memoryTools.suggest_decision.description,
|
|
234
|
+
inputSchema: {
|
|
235
|
+
type: 'object',
|
|
236
|
+
properties: {
|
|
237
|
+
query: {
|
|
238
|
+
type: 'string',
|
|
239
|
+
description: 'Search query. Semantic search finds related decisions.',
|
|
240
|
+
},
|
|
241
|
+
type: {
|
|
242
|
+
type: 'string',
|
|
243
|
+
enum: ['all', 'decision', 'checkpoint'],
|
|
244
|
+
description: "Filter by type. Default: 'all'",
|
|
245
|
+
},
|
|
246
|
+
limit: { type: 'number', description: 'Maximum results. Default: 10' },
|
|
247
|
+
scopes: memoryTools.save_decision.inputSchema.properties.scopes,
|
|
447
248
|
},
|
|
448
249
|
},
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
name: 'update',
|
|
253
|
+
description: memoryTools.update_outcome.description,
|
|
254
|
+
inputSchema: memoryTools.update_outcome.inputSchema,
|
|
255
|
+
},
|
|
256
|
+
];
|
|
257
|
+
|
|
258
|
+
// All tools: legacy wrappers + all v2 tools from src/tools/
|
|
259
|
+
const v2Tools = Object.values(memoryTools)
|
|
260
|
+
.filter((t) => t.name && t.inputSchema)
|
|
261
|
+
.map((t) => ({ name: t.name, description: t.description, inputSchema: t.inputSchema }));
|
|
262
|
+
|
|
263
|
+
this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
264
|
+
tools: [...legacyTools, ...v2Tools],
|
|
458
265
|
}));
|
|
459
266
|
|
|
460
|
-
// Handle tool execution
|
|
267
|
+
// Handle tool execution β legacy wrappers + v2 tools from src/tools/
|
|
461
268
|
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
462
269
|
const { name, arguments: args } = request.params;
|
|
463
270
|
const toolStart = Date.now();
|
|
@@ -467,6 +274,7 @@ Returns: summary (4-section), next_steps (DoD + commands), open_files
|
|
|
467
274
|
let result;
|
|
468
275
|
|
|
469
276
|
switch (name) {
|
|
277
|
+
// Legacy unified wrappers (backward compat)
|
|
470
278
|
case 'save':
|
|
471
279
|
result = await this.handleSave(args);
|
|
472
280
|
break;
|
|
@@ -476,14 +284,8 @@ Returns: summary (4-section), next_steps (DoD + commands), open_files
|
|
|
476
284
|
case 'update':
|
|
477
285
|
result = await this.handleUpdate(args);
|
|
478
286
|
break;
|
|
479
|
-
case 'search_decisions_and_contracts':
|
|
480
|
-
result = await this.handleSearchDecisionsAndContracts(args);
|
|
481
|
-
break;
|
|
482
|
-
case 'load_checkpoint':
|
|
483
|
-
result = await memoryTools.load_checkpoint.handler(args);
|
|
484
|
-
break;
|
|
485
287
|
default:
|
|
486
|
-
//
|
|
288
|
+
// All other tools β src/tools/ handlers (single source of truth)
|
|
487
289
|
if (memoryTools[name] && typeof memoryTools[name].handler === 'function') {
|
|
488
290
|
result = await memoryTools[name].handler(args);
|
|
489
291
|
} else {
|