| """
|
| Cognitive Router - Orchestrates System 1 (Fast) and System 2 (Slow) thinking.
|
| """
|
|
|
| import time
|
| from typing import Dict, Any, Tuple, Optional
|
| from loguru import logger
|
|
|
| from .engine import HAIMEngine
|
| from .binary_hdv import majority_bundle, BinaryHDV
|
| from .exceptions import MnemoCoreError
|
|
|
|
|
| class CognitiveRouter:
|
| """
|
| Orchestrates System 1 (Fast) and System 2 (Slow) thinking.
|
|
|
| System 1: Intuitive, heuristic, fast memory retrieval.
|
| System 2: Analytical, epistemic search, heavy reasoning.
|
| """
|
|
|
| def __init__(self, engine: HAIMEngine):
|
| self.engine = engine
|
| self.complexity_threshold = 0.6
|
|
|
| async def route(self, impulse: str, context: dict = None) -> Tuple[str, Dict[str, Any]]:
|
| """
|
| Route the impulse to the appropriate system.
|
| Returns: (response, debug_info)
|
| """
|
| start_time = time.time()
|
| complexity = await self._assess_complexity(impulse)
|
|
|
| debug_info = {
|
| "impulse": impulse,
|
| "complexity_score": complexity,
|
| "timestamp": start_time
|
| }
|
|
|
| if complexity < self.complexity_threshold:
|
|
|
| debug_info["system"] = "Sys1 (Fast)"
|
| response = await self._system_1_reflex(impulse)
|
| else:
|
|
|
| debug_info["system"] = "Sys2 (Slow)"
|
| response = await self._system_2_reasoning(impulse, context)
|
|
|
| debug_info["duration"] = time.time() - start_time
|
| return response, debug_info
|
|
|
| async def _assess_complexity(self, text: str) -> float:
|
| """
|
| Heuristic to estimate cognitive load.
|
| """
|
| score = 0.0
|
|
|
|
|
| if len(text.split()) > 20:
|
| score += 0.3
|
|
|
|
|
| complex_markers = ["analyze", "compare", "why", "how", "plan", "design", "evaluate"]
|
| if any(marker in text.lower() for marker in complex_markers):
|
| score += 0.4
|
|
|
|
|
| uncertainty = ["maybe", "unsure", "unknown", "complex"]
|
| if any(u in text.lower() for u in uncertainty):
|
| score += 0.2
|
|
|
|
|
|
|
| try:
|
| results = await self.engine.query(text, top_k=1, associative_jump=False)
|
| if results and results[0][1] > 0.8:
|
|
|
| score -= 0.3
|
| elif not results or results[0][1] < 0.3:
|
|
|
| score += 0.4
|
| except MnemoCoreError as e:
|
|
|
| logger.debug(f"Complexity assessment query failed: {e}")
|
| except Exception as e:
|
|
|
| logger.warning(f"Unexpected error in complexity assessment: {e}")
|
|
|
| return min(1.0, max(0.0, score))
|
|
|
| async def _system_1_reflex(self, impulse: str) -> str:
|
| """
|
| Fast retrieval and simple association.
|
| """
|
|
|
| results = await self.engine.query(impulse, top_k=3)
|
|
|
| if not results:
|
| return "I don't have an immediate reflex for that."
|
|
|
|
|
|
|
| top_mem_id, score = results[0]
|
| node = await self.engine.get_memory(top_mem_id)
|
|
|
| content = node.content if node else 'Unknown'
|
| return f"[Reflex] Based on memory ({score:.2f}): {content}"
|
|
|
| async def _system_2_reasoning(self, impulse: str, context: Optional[dict]) -> str:
|
| """Slow, deliberative process with Epistemic Drive."""
|
| eig: Optional[float] = None
|
|
|
|
|
| if self.engine.epistemic_drive_active:
|
| candidate_vec = self.engine.encode_content(impulse)
|
|
|
|
|
| ctx_vec: BinaryHDV
|
|
|
| if context and isinstance(context.get("working_memory"), list) and context["working_memory"]:
|
| vectors = []
|
| for item in context["working_memory"]:
|
| vectors.append(self.engine.encode_content(str(item)))
|
|
|
|
|
| if vectors:
|
| ctx_vec = majority_bundle(vectors)
|
| else:
|
| ctx_vec = await self.engine._current_context_vector()
|
| else:
|
| ctx_vec = await self.engine._current_context_vector(sample_n=50)
|
|
|
| eig = self.engine.calculate_eig(candidate_vec, ctx_vec)
|
|
|
|
|
| results = await self.engine.query(impulse, top_k=10, associative_jump=True)
|
|
|
|
|
| memories = []
|
| for mid, score in results:
|
| node = await self.engine.get_memory(mid)
|
| if node:
|
| memories.append(f"- {node.content} (conf: {score:.2f})")
|
|
|
| knowledge_block = "\n".join(memories)
|
|
|
| eig_line = f"\nEpistemic Drive (EIG): {eig:.2f}" if eig is not None else ""
|
| return f"[Reasoning] I have analyzed {len(memories)} data points.{eig_line}\nKey insights:\n{knowledge_block}"
|
|
|