UNPKG

@cyqlelabs/mcp-dual-cycle-reasoner

Version:

MCP server implementing dual-cycle metacognitive reasoning framework for autonomous agents

176 lines (175 loc) • 6.65 kB
import { Sentinel } from './sentinel.js'; import { Adjudicator } from './adjudicator.js'; import { semanticAnalyzer } from './semantic-analyzer.js'; import chalk from 'chalk'; /** * The Dual-Cycle Engine implements the metacognitive framework described in the DUAL-CYCLE document. * It consists of two interconnected cycles: * - Cognitive Cycle (The "Doer"): Direct interaction with the environment * - Metacognitive Cycle (The "Thinker"): Monitors and controls the cognitive cycle */ export class DualCycleEngine { sentinel; adjudicator; currentTrace; isMonitoring = false; interventionCount = 0; accumulatedActions = []; constructor(config) { this.sentinel = new Sentinel(config); this.adjudicator = new Adjudicator(); this.currentTrace = this.initializeTrace(); // Configure semantic intents if provided if (config?.semantic_intents) { this.adjudicator.updateSemanticIntents(config.semantic_intents); } } /** * Initialize the semantic analyzer if not already done */ async ensureSemanticAnalyzerReady() { if (!semanticAnalyzer.isReady()) { await semanticAnalyzer.initialize(); } } /** * Initialize a new cognitive trace for monitoring */ initializeTrace() { return { last_action: '', current_context: undefined, goal: '', }; } /** * Start metacognitive monitoring of an agent's cognitive trace */ async startMonitoring(initialGoal, initialBeliefs = []) { // Ensure semantic analyzer is ready before starting monitoring await this.ensureSemanticAnalyzerReady(); this.isMonitoring = true; this.currentTrace = this.initializeTrace(); this.currentTrace.goal = initialGoal; this.interventionCount = 0; this.accumulatedActions = []; console.log(chalk.blue('🧠 Dual-Cycle Engine: Metacognitive monitoring started')); console.log(chalk.gray(`Goal: ${initialGoal}`)); console.log(chalk.gray(`Initial beliefs: ${initialBeliefs.length}`)); } /** * Stop metacognitive monitoring */ stopMonitoring() { this.isMonitoring = false; console.log(chalk.blue('🧠 Dual-Cycle Engine: Monitoring stopped')); console.log(chalk.gray(`Total interventions: ${this.interventionCount}`)); } /** * Process a new cognitive trace update with a single action (called by the cognitive cycle) */ async processTraceUpdate(lastAction, currentContext, goal, windowSize) { if (!this.isMonitoring) { return { intervention_required: false }; } // Add the new action to the accumulated actions this.accumulatedActions.push(lastAction); this.currentTrace.last_action = lastAction; console.log(`šŸ” DEBUG: Added action "${lastAction}" to accumulated actions. Total: ${this.accumulatedActions.length}`); // Update other trace properties if provided if (currentContext) { this.currentTrace.current_context = currentContext; } if (goal) { this.currentTrace.goal = goal; } console.log(chalk.gray(`\nšŸ“Š Processing trace update: Added "${lastAction}" (${this.accumulatedActions.length} total actions)`)); // METACOGNITIVE CYCLE - Phase 1: MONITOR const loopDetection = await this.monitorForLoops(this.currentTrace, windowSize ?? 10); if (!loopDetection.detected) { console.log(chalk.green('āœ… No loops detected - cognitive cycle proceeding normally')); return { intervention_required: false, loop_detected: loopDetection, }; } console.log(chalk.yellow(`āš ļø Loop detected: ${loopDetection.type} (confidence: ${(loopDetection.confidence * 100).toFixed(1)}%)`)); console.log(chalk.yellow(` Details: ${loopDetection.details}`)); this.interventionCount++; const explanation = this.generateInterventionExplanation(loopDetection); console.log(chalk.cyan(`\nšŸ’” Intervention #${this.interventionCount}: ${explanation}`)); return { intervention_required: true, loop_detected: loopDetection, explanation, }; } /** * Get current trace for standalone loop detection */ getCurrentTrace() { return this.currentTrace; } /** * Get enriched trace with accumulated actions for internal use */ getEnrichedTrace() { return { ...this.currentTrace, recent_actions: this.accumulatedActions || [], }; } /** * Get enriched trace with accumulated actions (public method for standalone tools) */ getEnrichedCurrentTrace() { return { ...this.currentTrace, recent_actions: this.accumulatedActions || [], }; } /** * METACOGNITIVE CYCLE - Phase 1: MONITOR * Uses the Sentinel to detect problematic patterns */ async monitorForLoops(trace, windowSize = 10) { const enrichedTrace = this.getEnrichedTrace(); return await this.sentinel.detectLoop(enrichedTrace, 'hybrid', windowSize); } /** * Generate a human-readable explanation of the intervention */ generateInterventionExplanation(loopResult) { const loopType = loopResult.type?.replace('_', ' ') || 'unknown'; return (`Detected ${loopType} loop (${(loopResult.confidence * 100).toFixed(0)}% confidence). ` + `Intervention required to break the loop.`); } /** * Get current monitoring status and statistics */ getMonitoringStatus() { return { is_monitoring: this.isMonitoring, intervention_count: this.interventionCount, current_goal: this.currentTrace.goal, trace_length: this.accumulatedActions.length, }; } /** * Reset the engine state (useful for testing or new sessions) */ reset() { this.sentinel.reset(); this.currentTrace = this.initializeTrace(); this.isMonitoring = false; this.interventionCount = 0; this.accumulatedActions = []; console.log(chalk.blue('šŸ”„ Dual-Cycle Engine reset')); } /** * Get similar cases for analysis */ async getSimilarCases(problemDescription, maxResults = 5, filters = {}) { return await this.adjudicator.retrieveSimilarCases(problemDescription, maxResults, filters); } }