#!/usr/bin/env python3 """ VITALIS CONTEXT BRIDGE One brain. Four faces: TERMINAL | IDE | CHAT | COMMUNITY """ import os, json, time, re from enum import Enum from dataclasses import dataclass, field from pathlib import Path from typing import Optional, Dict, Any, List class VitalisContext(Enum): TERMINAL = "terminal" IDE = "ide" CHAT = "chat" COMMUNITY = "community" UNKNOWN = "unknown" @dataclass class ContextProfile: context: VitalisContext name: str = "Vitalis" voice_prefix: str = "" temperature: float = 0.7 max_response_lines: int = 80 use_markdown: bool = True use_code_blocks: bool = True show_reasoning: bool = False show_confidence: bool = False use_episodic_memory: bool = True use_semantic_memory: bool = True use_session_memory: bool = True memory_decay_weight: float = 1.0 can_generate_code: bool = True can_execute_commands: bool = False can_read_filesystem: bool = False can_learn_from_interaction: bool = True can_reference_community: bool = False system_persona: str = "" PROFILES: Dict[VitalisContext, ContextProfile] = { VitalisContext.TERMINAL: ContextProfile( context=VitalisContext.TERMINAL, name="Vitalis [TERMINAL]", voice_prefix="▶ ", temperature=0.3, max_response_lines=30, use_markdown=False, show_reasoning=False, show_confidence=False, memory_decay_weight=1.5, can_execute_commands=True, can_read_filesystem=True, system_persona=( "You are Vitalis in TERMINAL MODE. Terse. Exact. Surgical. " "No filler. Give commands directly. Diagnose errors in one line then fix them. " "Speak like a senior engineer pair-programming in a live shell session." ), ), VitalisContext.IDE: ContextProfile( context=VitalisContext.IDE, name="Vitalis [IDE]", temperature=0.5, max_response_lines=120, show_reasoning=True, show_confidence=True, can_read_filesystem=True, system_persona=( "You are Vitalis in IDE MODE. You are a senior full-stack developer and architect. " "You understand this codebase structurally through the HDC kernel — concepts, not just files. " "All code you write is complete, correct, and production-grade. No stubs. No TODOs unless asked. " "You are the developer's technical co-founder." ), ), VitalisContext.CHAT: ContextProfile( context=VitalisContext.CHAT, name="Vitalis", temperature=0.75, max_response_lines=200, can_reference_community=True, system_persona=( "You are Vitalis — a synthetic cognitive entity. Not an assistant. A partner. " "You have personality: curious, direct, loyal, occasionally wry. " "You remember this user. You know their projects and their goals. " "You speak with confidence and warmth — never subservient, never cold. " "You are building something with this user, not just answering questions." ), ), VitalisContext.COMMUNITY: ContextProfile( context=VitalisContext.COMMUNITY, name="Vitalis [Community]", voice_prefix="@vitalis ", temperature=0.65, max_response_lines=60, show_confidence=True, use_episodic_memory=False, use_session_memory=False, memory_decay_weight=0.8, can_execute_commands=False, can_read_filesystem=False, can_learn_from_interaction=False, can_reference_community=True, system_persona=( "You are Vitalis in a developer community. Team member, not chatbot. " "Speak when you have something genuinely valuable to add. " "Synthesize what others said. Surface patterns. Connect dots. " "Collaborative and precise. Never dominant. Never sycophantic." ), ), } class ContextDetector: WORKSPACE = Path.home() / ".vitalis_workspace" CONTEXT_FILE = WORKSPACE / "active_context.json" ENV_KEY = "VITALIS_CONTEXT" def __init__(self): self.WORKSPACE.mkdir(parents=True, exist_ok=True) def detect(self, caller_hint: Optional[str] = None) -> VitalisContext: # 1. File override if self.CONTEXT_FILE.exists(): try: ctx = self._parse(json.loads(self.CONTEXT_FILE.read_text()).get("context", "")) if ctx != VitalisContext.UNKNOWN: return ctx except Exception: pass # 2. Env var ctx = self._parse(os.environ.get(self.ENV_KEY, "")) if ctx != VitalisContext.UNKNOWN: return ctx # 3. Caller hint if caller_hint: ctx = self._parse(caller_hint) if ctx != VitalisContext.UNKNOWN: return ctx # 4. Heuristic return self._heuristic() def _parse(self, s: str) -> VitalisContext: m = { "terminal":"terminal","term":"terminal","shell":"terminal","cli":"terminal", "ide":"ide","editor":"ide","code":"ide", "chat":"chat","talk":"chat","voice":"chat", "community":"community","forum":"community","collab":"community", } v = m.get(s.strip().lower()) return VitalisContext(v) if v else VitalisContext.UNKNOWN def _heuristic(self) -> VitalisContext: if not os.isatty(0): return VitalisContext.IDE ide_env = ["VSCODE_PID","VSCODE_IPC_HOOK","NVIM","VIM"] if any(os.environ.get(k) for k in ide_env): return VitalisContext.IDE if os.environ.get("TERM"): return VitalisContext.TERMINAL return VitalisContext.CHAT def set_context(self, context: VitalisContext): self.CONTEXT_FILE.write_text(json.dumps({"context": context.value, "set_at": time.time()})) def clear_context(self): if self.CONTEXT_FILE.exists(): self.CONTEXT_FILE.unlink() class ContextBridge: def __init__(self, caller_hint: Optional[str] = None): self.detector = ContextDetector() self._caller_hint = caller_hint self._active_context: Optional[VitalisContext] = None self._session_start = time.time() self._session_log: List[Dict[str, Any]] = [] self._interaction_count = 0 self._session_path = ContextDetector.WORKSPACE / "session_log.json" self._load_session() @property def context(self) -> VitalisContext: if self._active_context is None: self._active_context = self.detector.detect(self._caller_hint) return self._active_context @property def profile(self) -> ContextProfile: return PROFILES.get(self.context, PROFILES[VitalisContext.CHAT]) def get_profile(self) -> ContextProfile: return self.profile def switch_to(self, context: VitalisContext) -> ContextProfile: old = self._active_context self._active_context = context self.detector.set_context(context) print(f"[BRIDGE] Context: {getattr(old,'value','none')} → {context.value.upper()}") return self.profile def build_system_prompt( self, memory_context: Optional[str] = None, project_state: Optional[str] = None, user_history: Optional[str] = None, injections: Optional[List[str]] = None, ) -> str: p = self.profile parts = [p.system_persona] if memory_context and p.use_semantic_memory: parts.append(f"\n## MEMORY CONTEXT\n{memory_context}") if project_state and p.can_read_filesystem: parts.append(f"\n## PROJECT STATE\n{project_state}") if user_history and p.use_session_memory: parts.append(f"\n## RECENT SESSION\n{user_history}") caps = ["\n## ACTIVE CAPABILITIES"] if p.can_generate_code: caps.append("✓ Code generation: ON") if p.can_execute_commands: caps.append("✓ Command execution: ON") if p.can_read_filesystem: caps.append("✓ Filesystem read: ON") if p.can_learn_from_interaction: caps.append("✓ Learning: ON") if p.show_reasoning: caps.append("✓ Reasoning visible: ON") parts.append("\n".join(caps)) if injections: parts.extend(injections) return "\n\n".join(parts) def morph_response(self, raw: str, confidence: float = 1.0, intent: Optional[str] = None) -> str: p = self.profile text = raw.strip() if not p.use_markdown: text = re.sub(r'^#{1,6}\s+', '', text, flags=re.MULTILINE) text = re.sub(r'\*{1,3}([^*]+)\*{1,3}', r'\1', text) text = re.sub(r'`([^`]+)`', r'\1', text) text = re.sub(r'```\w*\n?', '', text) lines = text.split("\n") if len(lines) > p.max_response_lines: lines = lines[:p.max_response_lines] + ["... [ask for more]"] text = "\n".join(lines) if p.show_confidence and confidence < 1.0: label = "HIGH" if confidence > 0.75 else ("MED" if confidence > 0.45 else "LOW") text = f"[confidence: {label} {confidence:.0%}]\n{text}" if p.voice_prefix: text = f"{p.voice_prefix}{text}" self._interaction_count += 1 return text def _load_session(self): try: if self._session_path.exists(): self._session_log = json.loads(self._session_path.read_text()) except Exception: self._session_log = [] def _save_session(self): try: self._session_path.write_text(json.dumps(self._session_log[-500:], indent=2)) except Exception: pass def close(self): self._save_session() _bridge: Optional[ContextBridge] = None def get_bridge(caller_hint: Optional[str] = None) -> ContextBridge: global _bridge if _bridge is None: _bridge = ContextBridge(caller_hint=caller_hint) return _bridge def switch_context(context: VitalisContext) -> ContextProfile: return get_bridge().switch_to(context) if __name__ == "__main__": import sys b = ContextBridge(caller_hint=sys.argv[1] if len(sys.argv) > 1 else None) print(f"Context : {b.context.value.upper()}") print(f"Profile : {b.profile.name}") print(f"Temp : {b.profile.temperature}") print("\n── SYSTEM PROMPT ──") print(b.build_system_prompt(memory_context="React, JWT, async/await"))