@ooples/token-optimizer-mcp
Version:
Intelligent context window optimization for Claude Code - store content externally via caching and compression, freeing up your context window for what matters
83 lines • 3.09 kB
JavaScript
/**
* Thinking Mode Detection Utilities
* Detects when Claude is in thinking mode based on tool usage patterns and token velocity
*/
/**
* Detects the mode of a turn based on tool usage and token patterns
*/
export function detectTurnMode(turns, averageTurnTokens) {
if (turns.length === 0)
return 'normal';
// Check for sequential thinking tool usage
const hasSequentialThinking = turns.some((t) => t.toolName.includes('sequential-thinking'));
if (hasSequentialThinking)
return 'thinking';
// Check for planning tools (task management, etc.)
const hasPlanningTools = turns.some((t) => t.toolName === 'ExitPlanMode' || t.toolName === 'TodoWrite');
if (hasPlanningTools)
return 'planning';
// Check for high token velocity (>2x average)
const totalTokens = turns.reduce((sum, t) => sum + t.tokens, 0);
if (totalTokens > averageTurnTokens * 2)
return 'thinking';
return 'normal';
}
/**
* Analyzes turns and groups them with mode detection
*/
export function analyzeTurns(operations) {
// Group operations by timestamp (each turn has same timestamp)
const turnMap = new Map();
for (const op of operations) {
if (!turnMap.has(op.timestamp)) {
turnMap.set(op.timestamp, []);
}
turnMap.get(op.timestamp).push(op);
}
// Calculate average turn tokens
const turns = Array.from(turnMap.entries());
const averageTurnTokens = turns.reduce((sum, [_, ops]) => sum + ops.reduce((s, o) => s + o.tokens, 0), 0) / turns.length;
// Analyze each turn
const turnSummaries = [];
let turnNumber = 1;
for (const [timestamp, ops] of turns) {
const totalTokens = ops.reduce((sum, o) => sum + o.tokens, 0);
const tools = [...new Set(ops.map((o) => o.toolName))];
const mode = detectTurnMode(ops, averageTurnTokens);
let reason = '';
switch (mode) {
case 'thinking':
if (ops.some((t) => t.toolName.includes('sequential-thinking'))) {
reason = 'Sequential thinking tool used';
}
else {
reason = `High token usage (${totalTokens} tokens, ${(totalTokens / averageTurnTokens).toFixed(1)}x average)`;
}
break;
case 'planning':
reason = 'Planning tools detected (TodoWrite, ExitPlanMode)';
break;
case 'normal':
reason = 'Normal operation';
break;
}
turnSummaries.push({
turnNumber,
timestamp,
tools,
totalTokens,
mode,
reason,
});
turnNumber++;
}
return turnSummaries;
}
/**
* Detects anomalies in turn token usage
*/
export function detectAnomalies(turns, threshold = 3) {
const averageTokens = turns.reduce((sum, t) => sum + t.totalTokens, 0) / turns.length;
return turns.filter((turn) => turn.totalTokens > averageTokens * threshold);
}
//# sourceMappingURL=thinking-mode.js.map