@jungjaehoon/mama-server 1.9.2 → 1.10.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 +17 -10
- package/package.json +2 -2
- package/src/server.js +6 -1
- package/src/tools/checkpoint-tools.js +2 -7
- package/src/tools/index.js +4 -0
- package/src/tools/ingest-conversation.js +99 -0
- package/src/tools/list-decisions.js +15 -5
- package/src/tools/recall-decision.js +68 -23
- package/src/tools/save-decision.js +33 -0
- package/src/tools/suggest-decision.js +15 -3
package/README.md
CHANGED
|
@@ -75,16 +75,23 @@ Any MCP-compatible client can use MAMA with:
|
|
|
75
75
|
npx -y @jungjaehoon/mama-server
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
-
## Available Tools (v1.
|
|
79
|
-
|
|
80
|
-
The MCP server exposes
|
|
81
|
-
|
|
82
|
-
| Tool
|
|
83
|
-
|
|
|
84
|
-
| `
|
|
85
|
-
| `
|
|
86
|
-
| `
|
|
87
|
-
| `
|
|
78
|
+
## Available Tools (v1.9)
|
|
79
|
+
|
|
80
|
+
The MCP server exposes 11 tools:
|
|
81
|
+
|
|
82
|
+
| Tool | Description |
|
|
83
|
+
| ------------------------- | ----------------------------------------------------------------------- |
|
|
84
|
+
| `save_decision` | Save decision with optional scopes and event_date for temporal tracking |
|
|
85
|
+
| `recall_decision` | Recall decision history by topic, scope-filtered via recallMemory v2 |
|
|
86
|
+
| `suggest_decision` | Semantic search for relevant past decisions, scope-aware |
|
|
87
|
+
| `list_decisions` | List recent decisions, scope-filterable |
|
|
88
|
+
| `update_outcome` | Update decision outcome (case-insensitive: success/failed/partial) |
|
|
89
|
+
| `search_narrative` | Narrative search with link expansion (depth 0-2) |
|
|
90
|
+
| `ingest_conversation` | Ingest conversation messages into memory with optional LLM extraction |
|
|
91
|
+
| `save_checkpoint` | Save session checkpoint for later resumption |
|
|
92
|
+
| `load_checkpoint` | Resume previous session |
|
|
93
|
+
| `generate_quality_report` | Quality metrics and observability report |
|
|
94
|
+
| `get_restart_metrics` | Restart success rate and latency monitoring |
|
|
88
95
|
|
|
89
96
|
### Edge Types
|
|
90
97
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jungjaehoon/mama-server",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.0",
|
|
4
4
|
"description": "MAMA MCP Server - Memory-Augmented MCP Assistant for Claude Code & Desktop",
|
|
5
5
|
"main": "src/server.js",
|
|
6
6
|
"bin": {
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"node": ">=22.13.0"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@jungjaehoon/mama-core": "^1.
|
|
42
|
+
"@jungjaehoon/mama-core": "^1.4.0",
|
|
43
43
|
"@modelcontextprotocol/sdk": "^1.0.1"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
package/src/server.js
CHANGED
|
@@ -415,6 +415,8 @@ Returns: summary (4-section), next_steps (DoD + commands), open_files
|
|
|
415
415
|
// Handle tool execution - 4 core tools only
|
|
416
416
|
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
417
417
|
const { name, arguments: args } = request.params;
|
|
418
|
+
const toolStart = Date.now();
|
|
419
|
+
console.error(`[MAMA MCP] Tool start: ${name}`);
|
|
418
420
|
|
|
419
421
|
try {
|
|
420
422
|
let result;
|
|
@@ -446,6 +448,8 @@ Returns: summary (4-section), next_steps (DoD + commands), open_files
|
|
|
446
448
|
this.legacyNoticeEmittedInToolResponse = true;
|
|
447
449
|
}
|
|
448
450
|
|
|
451
|
+
console.error(`[MAMA MCP] Tool done: ${name} (${Date.now() - toolStart}ms)`);
|
|
452
|
+
|
|
449
453
|
return {
|
|
450
454
|
content: [
|
|
451
455
|
{
|
|
@@ -464,6 +468,7 @@ Returns: summary (4-section), next_steps (DoD + commands), open_files
|
|
|
464
468
|
],
|
|
465
469
|
};
|
|
466
470
|
} catch (error) {
|
|
471
|
+
console.error(`[MAMA MCP] Tool failed: ${name} (${Date.now() - toolStart}ms)`);
|
|
467
472
|
console.error('[MAMA MCP] Tool execution error:', error);
|
|
468
473
|
return {
|
|
469
474
|
content: [
|
|
@@ -489,7 +494,7 @@ Returns: summary (4-section), next_steps (DoD + commands), open_files
|
|
|
489
494
|
if (!topic || !decision || !reasoning) {
|
|
490
495
|
return { success: false, message: '❌ Decision requires: topic, decision, reasoning' };
|
|
491
496
|
}
|
|
492
|
-
const id = await mama.save({ topic, decision, reasoning, confidence });
|
|
497
|
+
const id = await mama.save({ type: 'user_decision', topic, decision, reasoning, confidence });
|
|
493
498
|
return {
|
|
494
499
|
success: true,
|
|
495
500
|
id,
|
|
@@ -235,10 +235,6 @@ const loadCheckpointTool = {
|
|
|
235
235
|
inputSchema: {
|
|
236
236
|
type: 'object',
|
|
237
237
|
properties: {
|
|
238
|
-
session_id: {
|
|
239
|
-
type: 'string',
|
|
240
|
-
description: 'Optional session ID. If not provided, loads the most recent checkpoint.',
|
|
241
|
-
},
|
|
242
238
|
include_narrative: {
|
|
243
239
|
type: 'boolean',
|
|
244
240
|
description: 'Include related narrative/decisions (default: true)',
|
|
@@ -258,8 +254,7 @@ const loadCheckpointTool = {
|
|
|
258
254
|
},
|
|
259
255
|
handler: async (args = {}) => {
|
|
260
256
|
const start = Date.now();
|
|
261
|
-
|
|
262
|
-
const { session_id, include_narrative = true, include_links = true, link_depth = 1 } = args;
|
|
257
|
+
const { include_narrative = true, include_links = true, link_depth = 1 } = args;
|
|
263
258
|
|
|
264
259
|
try {
|
|
265
260
|
const adapter = getAdapter();
|
|
@@ -338,7 +333,7 @@ const loadCheckpointTool = {
|
|
|
338
333
|
const formattedResponse = formatRestart(checkpoint, narrative, links);
|
|
339
334
|
|
|
340
335
|
// BMad Workflow Integration: Add Story context
|
|
341
|
-
const currentStory = inferCurrentStory(checkpoint.summary);
|
|
336
|
+
const currentStory = include_narrative ? inferCurrentStory(checkpoint.summary) : null;
|
|
342
337
|
let bmadWorkflowContext = '';
|
|
343
338
|
|
|
344
339
|
if (currentStory && currentStory.details) {
|
package/src/tools/index.js
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
* - search_narrative: Semantic search with link expansion ✅
|
|
16
16
|
* - generate_quality_report: Generate coverage and quality metrics report ✅
|
|
17
17
|
* - get_restart_metrics: Get restart success rate and latency metrics ✅
|
|
18
|
+
* - ingest_conversation: Ingest conversation messages into memory ✅
|
|
18
19
|
*
|
|
19
20
|
* @module tools
|
|
20
21
|
*/
|
|
@@ -27,6 +28,7 @@ const { updateOutcomeTool } = require('./update-outcome.js');
|
|
|
27
28
|
const { saveCheckpointTool, loadCheckpointTool } = require('./checkpoint-tools.js');
|
|
28
29
|
const { searchNarrativeTool } = require('./search-narrative.js');
|
|
29
30
|
const { generateQualityReportTool, getRestartMetricsTool } = require('./quality-metrics-tools.js');
|
|
31
|
+
const { ingestConversationTool } = require('./ingest-conversation.js');
|
|
30
32
|
|
|
31
33
|
/**
|
|
32
34
|
* Create all MAMA memory tools
|
|
@@ -47,6 +49,7 @@ function createMemoryTools() {
|
|
|
47
49
|
search_narrative: searchNarrativeTool,
|
|
48
50
|
generate_quality_report: generateQualityReportTool,
|
|
49
51
|
get_restart_metrics: getRestartMetricsTool,
|
|
52
|
+
ingest_conversation: ingestConversationTool,
|
|
50
53
|
};
|
|
51
54
|
}
|
|
52
55
|
|
|
@@ -63,4 +66,5 @@ module.exports = {
|
|
|
63
66
|
searchNarrativeTool,
|
|
64
67
|
generateQualityReportTool,
|
|
65
68
|
getRestartMetricsTool,
|
|
69
|
+
ingestConversationTool,
|
|
66
70
|
};
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Tool: ingest_conversation
|
|
3
|
+
*
|
|
4
|
+
* Ingests conversation messages into MAMA memory with optional extraction.
|
|
5
|
+
*
|
|
6
|
+
* @module ingest-conversation
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const { ingestConversation } = require('@jungjaehoon/mama-core');
|
|
10
|
+
|
|
11
|
+
const createIngestConversationTool = (mamaApi) => ({
|
|
12
|
+
name: 'ingest_conversation',
|
|
13
|
+
description:
|
|
14
|
+
"Ingest a conversation into MAMA's memory. Stores the raw conversation and optionally extracts structured memories (decisions, facts, preferences) using LLM. Use this to import past conversations or chat logs into memory.",
|
|
15
|
+
inputSchema: {
|
|
16
|
+
type: 'object',
|
|
17
|
+
properties: {
|
|
18
|
+
messages: {
|
|
19
|
+
type: 'array',
|
|
20
|
+
items: {
|
|
21
|
+
type: 'object',
|
|
22
|
+
properties: {
|
|
23
|
+
role: { type: 'string', enum: ['user', 'assistant', 'system'] },
|
|
24
|
+
content: { type: 'string' },
|
|
25
|
+
},
|
|
26
|
+
required: ['role', 'content'],
|
|
27
|
+
},
|
|
28
|
+
description: 'Conversation messages to ingest.',
|
|
29
|
+
},
|
|
30
|
+
scopes: {
|
|
31
|
+
type: 'array',
|
|
32
|
+
items: {
|
|
33
|
+
type: 'object',
|
|
34
|
+
properties: {
|
|
35
|
+
kind: { type: 'string', enum: ['global', 'user', 'channel', 'project'] },
|
|
36
|
+
id: { type: 'string' },
|
|
37
|
+
},
|
|
38
|
+
required: ['kind', 'id'],
|
|
39
|
+
},
|
|
40
|
+
description: 'Memory scopes for isolation.',
|
|
41
|
+
},
|
|
42
|
+
session_date: {
|
|
43
|
+
type: 'string',
|
|
44
|
+
description: 'ISO 8601 date when the conversation occurred (e.g., "2024-01-15").',
|
|
45
|
+
},
|
|
46
|
+
extract: {
|
|
47
|
+
type: 'boolean',
|
|
48
|
+
description: 'Whether to extract structured memories from the conversation. Default: false',
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
required: ['messages'],
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
async handler(params, _context) {
|
|
55
|
+
const { messages, scopes, session_date, extract = false } = params || {};
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
if (!messages || !Array.isArray(messages) || messages.length === 0) {
|
|
59
|
+
return {
|
|
60
|
+
success: false,
|
|
61
|
+
message: '❌ Validation error: messages must be a non-empty array',
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const ingestFn = mamaApi.ingestConversation || ingestConversation;
|
|
66
|
+
const result = await ingestFn({
|
|
67
|
+
messages,
|
|
68
|
+
scopes: scopes || [],
|
|
69
|
+
source: {
|
|
70
|
+
package: 'mcp-server',
|
|
71
|
+
source_type: 'mcp_ingest_conversation',
|
|
72
|
+
},
|
|
73
|
+
...(session_date && { sessionDate: session_date }),
|
|
74
|
+
...(extract && { extract: { enabled: true } }),
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
return {
|
|
78
|
+
success: true,
|
|
79
|
+
raw_id: result.rawId,
|
|
80
|
+
extracted_memories: result.extractedMemories || [],
|
|
81
|
+
message: `✅ Conversation ingested (ID: ${result.rawId})${
|
|
82
|
+
result.extractedMemories?.length
|
|
83
|
+
? `, extracted ${result.extractedMemories.length} memories`
|
|
84
|
+
: ''
|
|
85
|
+
}`,
|
|
86
|
+
};
|
|
87
|
+
} catch (error) {
|
|
88
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
|
|
89
|
+
return {
|
|
90
|
+
success: false,
|
|
91
|
+
message: `❌ Failed to ingest conversation: ${errorMessage}`,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
const ingestConversationTool = createIngestConversationTool({});
|
|
98
|
+
|
|
99
|
+
module.exports = { ingestConversationTool, createIngestConversationTool };
|
|
@@ -26,7 +26,7 @@ const mama = require('@jungjaehoon/mama-core/mama-api');
|
|
|
26
26
|
const listDecisionsTool = {
|
|
27
27
|
name: 'list_decisions',
|
|
28
28
|
description:
|
|
29
|
-
'List recent decisions in chronological order. Returns formatted list showing time, type (user/assistant), topic, preview, confidence, and status. Use this to see recent activity or find decisions by browsing.',
|
|
29
|
+
'List recent decisions in chronological order. Returns formatted list showing time, type (user/assistant), topic, preview, confidence, and status. Use this to see recent activity or find decisions by browsing. Use scopes to filter by project/channel.',
|
|
30
30
|
inputSchema: {
|
|
31
31
|
type: 'object',
|
|
32
32
|
properties: {
|
|
@@ -36,12 +36,24 @@ const listDecisionsTool = {
|
|
|
36
36
|
minimum: 1,
|
|
37
37
|
maximum: 100,
|
|
38
38
|
},
|
|
39
|
+
scopes: {
|
|
40
|
+
type: 'array',
|
|
41
|
+
items: {
|
|
42
|
+
type: 'object',
|
|
43
|
+
properties: {
|
|
44
|
+
kind: { type: 'string', enum: ['global', 'user', 'channel', 'project'] },
|
|
45
|
+
id: { type: 'string' },
|
|
46
|
+
},
|
|
47
|
+
required: ['kind', 'id'],
|
|
48
|
+
},
|
|
49
|
+
description: 'Filter list by scope. If omitted, lists all scopes.',
|
|
50
|
+
},
|
|
39
51
|
},
|
|
40
52
|
required: [],
|
|
41
53
|
},
|
|
42
54
|
|
|
43
55
|
async handler(params, _context) {
|
|
44
|
-
const { limit = 20 } = params || {};
|
|
56
|
+
const { limit = 20, scopes } = params || {};
|
|
45
57
|
|
|
46
58
|
try {
|
|
47
59
|
// Validation: Limit range check
|
|
@@ -52,9 +64,7 @@ const listDecisionsTool = {
|
|
|
52
64
|
};
|
|
53
65
|
}
|
|
54
66
|
|
|
55
|
-
|
|
56
|
-
// mama.list() defaults to JSON (LLM-first), but we need markdown for user display
|
|
57
|
-
const list = await mama.list({ limit, format: 'markdown' });
|
|
67
|
+
const list = await mama.list({ limit, format: 'markdown', ...(scopes && { scopes }) });
|
|
58
68
|
|
|
59
69
|
// Return success response with formatted list
|
|
60
70
|
return {
|
|
@@ -4,15 +4,8 @@
|
|
|
4
4
|
* Story M1.3: MCP Tool - recall_decision (ported from mcp-server)
|
|
5
5
|
* Priority: P1 (Core Feature)
|
|
6
6
|
*
|
|
7
|
-
* Recalls
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* Flow:
|
|
11
|
-
* 1. User (via Claude Desktop): "Recall my decision about auth strategy"
|
|
12
|
-
* 2. Claude: Calls recall_decision MCP tool
|
|
13
|
-
* 3. Tool: Validates input, calls mama.recall()
|
|
14
|
-
* 4. mama.recall(): Queries decision history + formats as markdown
|
|
15
|
-
* 5. Tool: Returns formatted markdown response
|
|
7
|
+
* Recalls decision history for a specific topic using v2 recallMemory API.
|
|
8
|
+
* Supports scope-based filtering.
|
|
16
9
|
*
|
|
17
10
|
* @module recall-decision
|
|
18
11
|
*/
|
|
@@ -20,26 +13,51 @@
|
|
|
20
13
|
const mama = require('@jungjaehoon/mama-core/mama-api');
|
|
21
14
|
|
|
22
15
|
/**
|
|
23
|
-
*
|
|
16
|
+
* Create recall decision tool with dependencies
|
|
17
|
+
* @param {Object} mamaApi - MAMA API instance
|
|
24
18
|
*/
|
|
25
|
-
const
|
|
19
|
+
const createRecallDecisionTool = (mamaApi) => ({
|
|
26
20
|
name: 'recall_decision',
|
|
27
21
|
description:
|
|
28
|
-
'Recall
|
|
22
|
+
'Recall decision history for a topic using semantic search. Returns past decisions filtered by scope if provided. Use this when you need to review previous decisions, understand decision evolution, or check current position on a topic.\n\n⚡ GRAPH TRAVERSAL: When the same topic is reused across multiple decisions, this tool automatically shows the decision evolution chain (supersedes graph), enabling Learn/Unlearn/Relearn workflows.',
|
|
29
23
|
inputSchema: {
|
|
30
24
|
type: 'object',
|
|
31
25
|
properties: {
|
|
32
26
|
topic: {
|
|
33
27
|
type: 'string',
|
|
34
28
|
description:
|
|
35
|
-
"Decision topic to recall (e.g., 'auth_strategy', 'mesh_detail_choice'). Use the EXACT SAME topic name used in save_decision to see full decision evolution graph.
|
|
29
|
+
"Decision topic to recall (e.g., 'auth_strategy', 'mesh_detail_choice'). Use the EXACT SAME topic name used in save_decision to see full decision evolution graph.",
|
|
30
|
+
},
|
|
31
|
+
format: {
|
|
32
|
+
type: 'string',
|
|
33
|
+
enum: ['markdown', 'json'],
|
|
34
|
+
description: "Output format. Default: 'markdown'",
|
|
35
|
+
},
|
|
36
|
+
scopes: {
|
|
37
|
+
type: 'array',
|
|
38
|
+
items: {
|
|
39
|
+
type: 'object',
|
|
40
|
+
properties: {
|
|
41
|
+
kind: {
|
|
42
|
+
type: 'string',
|
|
43
|
+
enum: ['global', 'user', 'channel', 'project'],
|
|
44
|
+
description: 'Scope type',
|
|
45
|
+
},
|
|
46
|
+
id: {
|
|
47
|
+
type: 'string',
|
|
48
|
+
description: 'Scope identifier (e.g., project path, channel ID)',
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
required: ['kind', 'id'],
|
|
52
|
+
},
|
|
53
|
+
description: 'Filter recall results by scope. If omitted, returns all scopes.',
|
|
36
54
|
},
|
|
37
55
|
},
|
|
38
56
|
required: ['topic'],
|
|
39
57
|
},
|
|
40
58
|
|
|
41
59
|
async handler(params, _context) {
|
|
42
|
-
const { topic } = params || {};
|
|
60
|
+
const { topic, format = 'markdown', scopes } = params || {};
|
|
43
61
|
|
|
44
62
|
try {
|
|
45
63
|
// Validation: Non-empty string check
|
|
@@ -50,26 +68,53 @@ const recallDecisionTool = {
|
|
|
50
68
|
};
|
|
51
69
|
}
|
|
52
70
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
71
|
+
if (scopes && scopes.length > 0) {
|
|
72
|
+
// Use v2 recallMemory for scope-aware semantic recall
|
|
73
|
+
const bundle = await mamaApi.recallMemory(topic, {
|
|
74
|
+
scopes,
|
|
75
|
+
includeHistory: true,
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
if (format === 'json') {
|
|
79
|
+
return { success: true, history: bundle, message: bundle };
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const memories = bundle.memories || [];
|
|
83
|
+
let md = `🧠 **Recall: ${topic}** (${memories.length} results)\n\n`;
|
|
84
|
+
for (const m of memories) {
|
|
85
|
+
md += `### ${m.topic}\n`;
|
|
86
|
+
md += `${m.summary}\n`;
|
|
87
|
+
if (m.details && m.details !== m.summary) {
|
|
88
|
+
md += `> ${m.details}\n`;
|
|
89
|
+
}
|
|
90
|
+
md += `- Confidence: ${m.confidence} | Status: ${m.status}`;
|
|
91
|
+
if (m.event_date) {
|
|
92
|
+
md += ` | Event: ${m.event_date}`;
|
|
93
|
+
}
|
|
94
|
+
md += '\n\n';
|
|
95
|
+
}
|
|
96
|
+
return { success: true, history: md, message: md };
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Legacy path: topic-exact-match recall (no scopes)
|
|
100
|
+
const history = await mamaApi.recall(topic, { format });
|
|
56
101
|
|
|
57
|
-
// Return success response with formatted history
|
|
58
102
|
return {
|
|
59
103
|
success: true,
|
|
60
104
|
history,
|
|
61
|
-
message: history,
|
|
105
|
+
message: history,
|
|
62
106
|
};
|
|
63
107
|
} catch (error) {
|
|
64
|
-
// Error handling: Return user-friendly message
|
|
65
108
|
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
|
|
66
|
-
|
|
67
109
|
return {
|
|
68
110
|
success: false,
|
|
69
111
|
message: `❌ Failed to recall decisions: ${errorMessage}`,
|
|
70
112
|
};
|
|
71
113
|
}
|
|
72
114
|
},
|
|
73
|
-
};
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
// Default instance with real dependency
|
|
118
|
+
const recallDecisionTool = createRecallDecisionTool(mama);
|
|
74
119
|
|
|
75
|
-
module.exports = { recallDecisionTool };
|
|
120
|
+
module.exports = { recallDecisionTool, createRecallDecisionTool };
|
|
@@ -149,6 +149,10 @@ When you find similar past decisions (returned in similar_decisions), choose you
|
|
|
149
149
|
- **debate**: Present a counter-argument with evidence. Explain why the prior decision may be wrong.
|
|
150
150
|
- **synthesize**: Merge multiple decisions into a new unified approach.
|
|
151
151
|
|
|
152
|
+
**SCOPES & TEMPORAL:**
|
|
153
|
+
- Use 'scopes' to isolate decisions per project/channel/user (e.g., [{"kind": "project", "id": "/my/app"}])
|
|
154
|
+
- Use 'event_date' (ISO 8601) to record when events actually happened vs. when they were saved
|
|
155
|
+
|
|
152
156
|
**5-LAYER REASONING (CoT Guide):**
|
|
153
157
|
Structure your reasoning with these layers for maximum value:
|
|
154
158
|
1. **Context**: What problem/situation prompted this decision?
|
|
@@ -211,6 +215,31 @@ Structure your reasoning with these layers for maximum value:
|
|
|
211
215
|
type: 'string',
|
|
212
216
|
description: 'Potential risks or downsides (Tension layer).',
|
|
213
217
|
},
|
|
218
|
+
scopes: {
|
|
219
|
+
type: 'array',
|
|
220
|
+
items: {
|
|
221
|
+
type: 'object',
|
|
222
|
+
properties: {
|
|
223
|
+
kind: {
|
|
224
|
+
type: 'string',
|
|
225
|
+
enum: ['global', 'user', 'channel', 'project'],
|
|
226
|
+
description: 'Scope type',
|
|
227
|
+
},
|
|
228
|
+
id: {
|
|
229
|
+
type: 'string',
|
|
230
|
+
description: 'Scope identifier (e.g., project path, channel ID)',
|
|
231
|
+
},
|
|
232
|
+
},
|
|
233
|
+
required: ['kind', 'id'],
|
|
234
|
+
},
|
|
235
|
+
description:
|
|
236
|
+
'Memory scopes for isolation. Decisions are stored per-scope. If omitted, decision is unscoped (global). Example: [{"kind": "project", "id": "/path/to/project"}]',
|
|
237
|
+
},
|
|
238
|
+
event_date: {
|
|
239
|
+
type: 'string',
|
|
240
|
+
description:
|
|
241
|
+
'ISO 8601 date when the event actually occurred (e.g., "2024-01-15"). If omitted, defaults to current time. Use this when recording decisions about past events.',
|
|
242
|
+
},
|
|
214
243
|
},
|
|
215
244
|
required: ['topic', 'decision', 'reasoning'],
|
|
216
245
|
},
|
|
@@ -226,6 +255,8 @@ Structure your reasoning with these layers for maximum value:
|
|
|
226
255
|
evidence,
|
|
227
256
|
alternatives,
|
|
228
257
|
risks,
|
|
258
|
+
scopes,
|
|
259
|
+
event_date,
|
|
229
260
|
} = params || {};
|
|
230
261
|
|
|
231
262
|
try {
|
|
@@ -305,6 +336,8 @@ Structure your reasoning with these layers for maximum value:
|
|
|
305
336
|
alternatives,
|
|
306
337
|
risks,
|
|
307
338
|
trust_context: trustContext,
|
|
339
|
+
...(scopes && { scopes }),
|
|
340
|
+
...(event_date && { event_date }),
|
|
308
341
|
});
|
|
309
342
|
|
|
310
343
|
// Story 1.2: Return enhanced response with collaborative fields
|
|
@@ -17,7 +17,7 @@ const mama = require('@jungjaehoon/mama-core/mama-api');
|
|
|
17
17
|
const suggestDecisionTool = {
|
|
18
18
|
name: 'suggest_decision',
|
|
19
19
|
description:
|
|
20
|
-
"Auto-suggest relevant past decisions based on user's question. Uses semantic search to find decisions related to the current context. Returns null if no relevant decisions found. Supports multilingual queries (English, Korean, etc.).",
|
|
20
|
+
"Auto-suggest relevant past decisions based on user's question. Uses semantic search to find decisions related to the current context. Returns null if no relevant decisions found. Supports multilingual queries (English, Korean, etc.). Use 'scopes' to filter by project/channel.",
|
|
21
21
|
inputSchema: {
|
|
22
22
|
type: 'object',
|
|
23
23
|
properties: {
|
|
@@ -48,12 +48,24 @@ const suggestDecisionTool = {
|
|
|
48
48
|
description: 'Optional: Disable recency weighting entirely. Default: false',
|
|
49
49
|
default: false,
|
|
50
50
|
},
|
|
51
|
+
scopes: {
|
|
52
|
+
type: 'array',
|
|
53
|
+
items: {
|
|
54
|
+
type: 'object',
|
|
55
|
+
properties: {
|
|
56
|
+
kind: { type: 'string', enum: ['global', 'user', 'channel', 'project'] },
|
|
57
|
+
id: { type: 'string' },
|
|
58
|
+
},
|
|
59
|
+
required: ['kind', 'id'],
|
|
60
|
+
},
|
|
61
|
+
description: 'Filter suggestions by scope. If omitted, searches all scopes.',
|
|
62
|
+
},
|
|
51
63
|
},
|
|
52
64
|
required: ['userQuestion'],
|
|
53
65
|
},
|
|
54
66
|
|
|
55
67
|
async handler(params, _context) {
|
|
56
|
-
const { userQuestion, recencyWeight, recencyScale, recencyDecay, disableRecency } =
|
|
68
|
+
const { userQuestion, recencyWeight, recencyScale, recencyDecay, disableRecency, scopes } =
|
|
57
69
|
params || {};
|
|
58
70
|
|
|
59
71
|
try {
|
|
@@ -65,13 +77,13 @@ const suggestDecisionTool = {
|
|
|
65
77
|
};
|
|
66
78
|
}
|
|
67
79
|
|
|
68
|
-
// Call MAMA API with markdown format
|
|
69
80
|
const suggestions = await mama.suggest(userQuestion, {
|
|
70
81
|
format: 'markdown',
|
|
71
82
|
recencyWeight,
|
|
72
83
|
recencyScale,
|
|
73
84
|
recencyDecay,
|
|
74
85
|
disableRecency,
|
|
86
|
+
...(scopes && { scopes }),
|
|
75
87
|
});
|
|
76
88
|
|
|
77
89
|
if (!suggestions) {
|