Skip to content

Commit 79f98d2

Browse files
Add missing Layer 1, 2, and 3 MCP tools
Expose all 9 missing Wake Intelligence tools as MCP endpoints: Layer 1 (Causality Engine): - reconstruct_reasoning: Explain WHY contexts were created - build_causal_chain: Trace decision history backwards - get_causality_stats: Analytics on causal relationships Layer 2 (Memory Manager): - get_memory_stats: View memory tier distribution - recalculate_memory_tiers: Update tier classifications - prune_expired_contexts: Clean up expired contexts Layer 3 (Propagation Engine): - update_predictions: Refresh prediction scores - get_high_value_contexts: Get contexts likely to be accessed next - get_propagation_stats: Analytics on prediction quality Fixes: - Fixed property name mismatches in stats handlers - Fixed CausalChainNode property access (node.snapshot.*) - All 12 tools now working and tested 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent b9c6f0b commit 79f98d2

File tree

2 files changed

+360
-0
lines changed

2 files changed

+360
-0
lines changed

src/application/handlers/MCPProtocolHandler.ts

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,111 @@ const TOOL_DEFINITIONS = [
5252
},
5353
required: ["query"]
5454
}
55+
},
56+
// Layer 1: Causality Engine (Past - WHY)
57+
{
58+
name: "reconstruct_reasoning",
59+
description: "Explain WHY a context was created by reconstructing the reasoning chain",
60+
inputSchema: {
61+
type: "object",
62+
properties: {
63+
snapshotId: { type: "string", description: "ID of the context snapshot to analyze" }
64+
},
65+
required: ["snapshotId"]
66+
}
67+
},
68+
{
69+
name: "build_causal_chain",
70+
description: "Trace decision history backwards through time to see how contexts influenced each other",
71+
inputSchema: {
72+
type: "object",
73+
properties: {
74+
snapshotId: { type: "string", description: "Starting snapshot ID to trace backwards from" }
75+
},
76+
required: ["snapshotId"]
77+
}
78+
},
79+
{
80+
name: "get_causality_stats",
81+
description: "Get analytics on causal relationships for a project",
82+
inputSchema: {
83+
type: "object",
84+
properties: {
85+
project: { type: "string", description: "Project identifier" }
86+
},
87+
required: ["project"]
88+
}
89+
},
90+
// Layer 2: Memory Manager (Present - HOW)
91+
{
92+
name: "get_memory_stats",
93+
description: "View memory tier distribution and access patterns for a project",
94+
inputSchema: {
95+
type: "object",
96+
properties: {
97+
project: { type: "string", description: "Project identifier" }
98+
},
99+
required: ["project"]
100+
}
101+
},
102+
{
103+
name: "recalculate_memory_tiers",
104+
description: "Update tier classifications based on current time",
105+
inputSchema: {
106+
type: "object",
107+
properties: {
108+
project: { type: "string", description: "Project to recalculate (optional, processes all if omitted)" }
109+
},
110+
required: []
111+
}
112+
},
113+
{
114+
name: "prune_expired_contexts",
115+
description: "Clean up old, unused contexts that have expired",
116+
inputSchema: {
117+
type: "object",
118+
properties: {
119+
limit: { type: "number", description: "Maximum number of contexts to prune (optional)" }
120+
},
121+
required: []
122+
}
123+
},
124+
// Layer 3: Propagation Engine (Future - WHAT)
125+
{
126+
name: "update_predictions",
127+
description: "Refresh prediction scores for a project's contexts",
128+
inputSchema: {
129+
type: "object",
130+
properties: {
131+
project: { type: "string", description: "Project identifier" },
132+
staleThreshold: { type: "number", description: "Hours threshold for stale predictions (default: 24)" }
133+
},
134+
required: ["project"]
135+
}
136+
},
137+
{
138+
name: "get_high_value_contexts",
139+
description: "Retrieve contexts most likely to be accessed next (predicted high-value)",
140+
inputSchema: {
141+
type: "object",
142+
properties: {
143+
project: { type: "string", description: "Project identifier" },
144+
minScore: { type: "number", description: "Minimum prediction score (default: 0.6)" },
145+
limit: { type: "number", description: "Maximum contexts to return (default: 5)" }
146+
},
147+
required: ["project"]
148+
}
149+
},
150+
{
151+
name: "get_propagation_stats",
152+
description: "Get analytics on prediction quality and patterns for a project",
153+
inputSchema: {
154+
type: "object",
155+
properties: {
156+
project: { type: "string", description: "Project identifier" }
157+
},
158+
required: ["project"]
159+
}
55160
}
56161
];
57162

src/application/handlers/ToolExecutionHandler.ts

Lines changed: 255 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,36 @@ export class ToolExecutionHandler {
4848
case 'search_context':
4949
return this.handleSearchContext(args as SearchContextInput);
5050

51+
// Layer 1: Causality Engine (Past - WHY)
52+
case 'reconstruct_reasoning':
53+
return this.handleReconstructReasoning(args as { snapshotId: string });
54+
55+
case 'build_causal_chain':
56+
return this.handleBuildCausalChain(args as { snapshotId: string });
57+
58+
case 'get_causality_stats':
59+
return this.handleGetCausalityStats(args as { project: string });
60+
61+
// Layer 2: Memory Manager (Present - HOW)
62+
case 'get_memory_stats':
63+
return this.handleGetMemoryStats(args as { project: string });
64+
65+
case 'recalculate_memory_tiers':
66+
return this.handleRecalculateMemoryTiers(args as { project?: string });
67+
68+
case 'prune_expired_contexts':
69+
return this.handlePruneExpiredContexts(args as { limit?: number });
70+
71+
// Layer 3: Propagation Engine (Future - WHAT)
72+
case 'update_predictions':
73+
return this.handleUpdatePredictions(args as { project: string; staleThreshold?: number });
74+
75+
case 'get_high_value_contexts':
76+
return this.handleGetHighValueContexts(args as { project: string; minScore?: number; limit?: number });
77+
78+
case 'get_propagation_stats':
79+
return this.handleGetPropagationStats(args as { project: string });
80+
5181
default:
5282
throw new Error(`Unknown tool: ${toolName}`);
5383
}
@@ -138,4 +168,229 @@ export class ToolExecutionHandler {
138168
}]
139169
};
140170
}
171+
172+
// =============================================================================
173+
// Layer 1: Causality Engine (Past - WHY)
174+
// =============================================================================
175+
176+
/**
177+
* 🎯 LAYER 1 TOOL: reconstruct_reasoning
178+
*
179+
* PURPOSE: Explain WHY a context was created
180+
*/
181+
private async handleReconstructReasoning(args: { snapshotId: string }): Promise<ToolResult> {
182+
const reasoning = await this.contextService.reconstructReasoning(args.snapshotId);
183+
184+
return {
185+
content: [{
186+
type: "text",
187+
text: reasoning
188+
}]
189+
};
190+
}
191+
192+
/**
193+
* 🎯 LAYER 1 TOOL: build_causal_chain
194+
*
195+
* PURPOSE: Trace decision history backwards through time
196+
*/
197+
private async handleBuildCausalChain(args: { snapshotId: string }): Promise<ToolResult> {
198+
const chain = await this.contextService.buildCausalChain(args.snapshotId);
199+
200+
if (chain.length === 0) {
201+
return {
202+
content: [{
203+
type: "text",
204+
text: `No causal chain found for snapshot: ${args.snapshotId}`
205+
}]
206+
};
207+
}
208+
209+
const chainText = chain
210+
.map((node, idx) => {
211+
const depth = ' '.repeat(idx);
212+
return `${depth}${idx + 1}. **${node.snapshot.causality?.actionType || 'unknown'}** (${node.snapshot.timestamp})\n${depth} ${node.snapshot.summary}`;
213+
})
214+
.join('\n\n');
215+
216+
return {
217+
content: [{
218+
type: "text",
219+
text: `Causal Chain (${chain.length} steps):\n\n${chainText}`
220+
}]
221+
};
222+
}
223+
224+
/**
225+
* 🎯 LAYER 1 TOOL: get_causality_stats
226+
*
227+
* PURPOSE: Analytics on causal relationships
228+
*/
229+
private async handleGetCausalityStats(args: { project: string }): Promise<ToolResult> {
230+
const stats = await this.contextService.getCausalityStats(args.project);
231+
232+
const statsText = `**Causality Statistics for ${args.project}**
233+
234+
📊 **Action Type Distribution:**
235+
${Object.entries(stats.actionTypeCounts)
236+
.map(([type, count]) => ` - ${type}: ${count}`)
237+
.join('\n')}
238+
239+
🔗 **Causal Analysis:**
240+
- Total contexts with causality: ${stats.totalWithCausality}
241+
- Root causes (no parent): ${stats.rootCauses}
242+
- Average chain length: ${stats.averageChainLength.toFixed(2)}`;
243+
244+
return {
245+
content: [{
246+
type: "text",
247+
text: statsText
248+
}]
249+
};
250+
}
251+
252+
// =============================================================================
253+
// Layer 2: Memory Manager (Present - HOW)
254+
// =============================================================================
255+
256+
/**
257+
* 🎯 LAYER 2 TOOL: get_memory_stats
258+
*
259+
* PURPOSE: View memory tier distribution and access patterns
260+
*/
261+
private async handleGetMemoryStats(args: { project: string }): Promise<ToolResult> {
262+
const stats = await this.contextService.getMemoryStats(args.project);
263+
264+
const statsText = `**Memory Statistics for ${args.project}**
265+
266+
📊 **Memory Tier Distribution:**
267+
- 🔥 ACTIVE (< 1 hour): ${stats.active}
268+
- ⚡ RECENT (1-24 hours): ${stats.recent}
269+
- 📦 ARCHIVED (1-30 days): ${stats.archived}
270+
- ❄️ EXPIRED (> 30 days): ${stats.expired}
271+
272+
📈 **Total Contexts:** ${stats.total}`;
273+
274+
return {
275+
content: [{
276+
type: "text",
277+
text: statsText
278+
}]
279+
};
280+
}
281+
282+
/**
283+
* 🎯 LAYER 2 TOOL: recalculate_memory_tiers
284+
*
285+
* PURPOSE: Update tier classifications based on current time
286+
*/
287+
private async handleRecalculateMemoryTiers(args: { project?: string }): Promise<ToolResult> {
288+
const updatedCount = await this.contextService.recalculateMemoryTiers(args.project);
289+
290+
return {
291+
content: [{
292+
type: "text",
293+
text: `✅ Recalculated memory tiers\n\nUpdated ${updatedCount} context(s)${args.project ? ` for project: ${args.project}` : ' across all projects'}`
294+
}]
295+
};
296+
}
297+
298+
/**
299+
* 🎯 LAYER 2 TOOL: prune_expired_contexts
300+
*
301+
* PURPOSE: Clean up old, unused contexts
302+
*/
303+
private async handlePruneExpiredContexts(args: { limit?: number }): Promise<ToolResult> {
304+
const deletedCount = await this.contextService.pruneExpiredContexts(args.limit);
305+
306+
return {
307+
content: [{
308+
type: "text",
309+
text: `🗑️ Pruned expired contexts\n\nDeleted ${deletedCount} expired context(s)`
310+
}]
311+
};
312+
}
313+
314+
// =============================================================================
315+
// Layer 3: Propagation Engine (Future - WHAT)
316+
// =============================================================================
317+
318+
/**
319+
* 🎯 LAYER 3 TOOL: update_predictions
320+
*
321+
* PURPOSE: Refresh prediction scores for a project
322+
*/
323+
private async handleUpdatePredictions(args: { project: string; staleThreshold?: number }): Promise<ToolResult> {
324+
const updatedCount = await this.contextService.updatePredictions(args.project, args.staleThreshold);
325+
326+
return {
327+
content: [{
328+
type: "text",
329+
text: `🔮 Updated predictions for ${args.project}\n\nRefreshed ${updatedCount} prediction(s) (stale threshold: ${args.staleThreshold || 24} hours)`
330+
}]
331+
};
332+
}
333+
334+
/**
335+
* 🎯 LAYER 3 TOOL: get_high_value_contexts
336+
*
337+
* PURPOSE: Retrieve contexts most likely to be accessed next
338+
*/
339+
private async handleGetHighValueContexts(args: { project: string; minScore?: number; limit?: number }): Promise<ToolResult> {
340+
const contexts = await this.contextService.getHighValueContexts(args.project, args.minScore, args.limit);
341+
342+
if (contexts.length === 0) {
343+
return {
344+
content: [{
345+
type: "text",
346+
text: `No high-value contexts found for ${args.project} (min score: ${args.minScore || 0.6})`
347+
}]
348+
};
349+
}
350+
351+
const contextList = contexts
352+
.map(ctx => {
353+
const score = ctx.propagation?.predictionScore || 0;
354+
const reasons = ctx.propagation?.propagationReason.join(', ') || 'none';
355+
return `**${ctx.project}** (Score: ${score.toFixed(3)})\n${ctx.summary}\nReasons: ${reasons}`;
356+
})
357+
.join('\n\n');
358+
359+
return {
360+
content: [{
361+
type: "text",
362+
text: `🎯 High-Value Contexts (${contexts.length} found):\n\n${contextList}`
363+
}]
364+
};
365+
}
366+
367+
/**
368+
* 🎯 LAYER 3 TOOL: get_propagation_stats
369+
*
370+
* PURPOSE: Analytics on prediction quality and patterns
371+
*/
372+
private async handleGetPropagationStats(args: { project: string }): Promise<ToolResult> {
373+
const stats = await this.contextService.getPropagationStats(args.project);
374+
375+
const reasonsText = Object.entries(stats.reasonFrequency)
376+
.map(([reason, count]) => ` - ${reason}: ${count}`)
377+
.join('\n');
378+
379+
const statsText = `**Propagation Statistics for ${args.project}**
380+
381+
🔮 **Predictions:**
382+
- Total contexts: ${stats.totalContexts}
383+
- Contexts predicted: ${stats.totalPredicted}
384+
- Average prediction score: ${stats.averagePredictionScore.toFixed(3)}
385+
386+
📊 **Prediction Reasons:**
387+
${reasonsText || ' - No predictions yet'}`;
388+
389+
return {
390+
content: [{
391+
type: "text",
392+
text: statsText
393+
}]
394+
};
395+
}
141396
}

0 commit comments

Comments
 (0)