#!/usr/bin/env python3 """ Uni-Wizard v4 — Unified Production API Single entry point for all uni-wizard capabilities. Usage: from uni_wizard import Harness, House, Mode # Simple mode - direct execution harness = Harness(mode=Mode.SIMPLE) result = harness.execute("git_status", repo_path="/path") # Intelligent mode - with predictions and learning harness = Harness(house=House.EZRA, mode=Mode.INTELLIGENT) result = harness.execute("git_status") print(f"Predicted: {result.prediction.success_rate:.0%}") # Sovereign mode - full provenance and approval harness = Harness(house=House.TIMMY, mode=Mode.SOVEREIGN) result = harness.execute("deploy") """ from enum import Enum, auto from typing import Dict, Any, Optional, List, Callable from dataclasses import dataclass, field from pathlib import Path import json import time import hashlib import asyncio from concurrent.futures import ThreadPoolExecutor class House(Enum): """Canonical wizard houses""" TIMMY = "timmy" # Sovereign local conscience EZRA = "ezra" # Archivist, reader BEZALEL = "bezalel" # Artificer, builder ALLEGRO = "allegro" # Tempo-and-dispatch, connected class Mode(Enum): """Operating modes""" SIMPLE = "simple" # Direct execution, no overhead INTELLIGENT = "intelligent" # With predictions and learning SOVEREIGN = "sovereign" # Full provenance, approval required @dataclass class Prediction: """Pre-execution prediction""" success_rate: float confidence: float reasoning: str suggested_house: Optional[str] = None estimated_latency_ms: float = 0.0 @dataclass class Provenance: """Full execution provenance""" house: str tool: str mode: str started_at: str completed_at: Optional[str] = None input_hash: str = "" output_hash: str = "" prediction: Optional[Prediction] = None execution_time_ms: float = 0.0 retry_count: int = 0 circuit_open: bool = False @dataclass class ExecutionResult: """Unified execution result""" success: bool data: Any provenance: Provenance error: Optional[str] = None suggestions: List[str] = field(default_factory=list) def to_json(self) -> str: return json.dumps({ "success": self.success, "data": self.data, "error": self.error, "provenance": { "house": self.provenance.house, "tool": self.provenance.tool, "mode": self.provenance.mode, "execution_time_ms": self.provenance.execution_time_ms, "prediction": { "success_rate": self.provenance.prediction.success_rate, "confidence": self.provenance.prediction.confidence } if self.provenance.prediction else None }, "suggestions": self.suggestions }, indent=2, default=str) class ToolRegistry: """Central tool registry""" def __init__(self): self._tools: Dict[str, Callable] = {} self._schemas: Dict[str, Dict] = {} def register(self, name: str, handler: Callable, schema: Dict = None): """Register a tool""" self._tools[name] = handler self._schemas[name] = schema or {} return self def get(self, name: str) -> Optional[Callable]: """Get tool handler""" return self._tools.get(name) def list_tools(self) -> List[str]: """List all registered tools""" return list(self._tools.keys()) class IntelligenceLayer: """ v4 Intelligence - pattern recognition and prediction. Lightweight version for production. """ def __init__(self, db_path: Path = None): self.patterns: Dict[str, Dict] = {} self.db_path = db_path or Path.home() / ".uni-wizard" / "patterns.json" self.db_path.parent.mkdir(parents=True, exist_ok=True) self._load_patterns() def _load_patterns(self): """Load patterns from disk""" if self.db_path.exists(): with open(self.db_path) as f: self.patterns = json.load(f) def _save_patterns(self): """Save patterns to disk""" with open(self.db_path, 'w') as f: json.dump(self.patterns, f, indent=2) def predict(self, tool: str, house: str, params: Dict) -> Prediction: """Predict execution outcome""" key = f"{house}:{tool}" pattern = self.patterns.get(key, {}) if not pattern or pattern.get("count", 0) < 3: return Prediction( success_rate=0.7, confidence=0.5, reasoning="Insufficient data for prediction", estimated_latency_ms=200 ) success_rate = pattern.get("successes", 0) / pattern.get("count", 1) avg_latency = pattern.get("total_latency_ms", 0) / pattern.get("count", 1) confidence = min(0.95, pattern.get("count", 0) / 20) # Max at 20 samples return Prediction( success_rate=success_rate, confidence=confidence, reasoning=f"Based on {pattern.get('count')} executions", estimated_latency_ms=avg_latency ) def record(self, tool: str, house: str, success: bool, latency_ms: float): """Record execution outcome""" key = f"{house}:{tool}" if key not in self.patterns: self.patterns[key] = {"count": 0, "successes": 0, "total_latency_ms": 0} self.patterns[key]["count"] += 1 self.patterns[key]["successes"] += int(success) self.patterns[key]["total_latency_ms"] += latency_ms self._save_patterns() class CircuitBreaker: """Circuit breaker pattern for fault tolerance""" def __init__(self, failure_threshold: int = 5, recovery_timeout: float = 60.0): self.failure_threshold = failure_threshold self.recovery_timeout = recovery_timeout self.failures: Dict[str, int] = {} self.last_failure: Dict[str, float] = {} self.open_circuits: set = set() def can_execute(self, tool: str) -> bool: """Check if tool can be executed""" if tool not in self.open_circuits: return True # Check if recovery timeout passed last_fail = self.last_failure.get(tool, 0) if time.time() - last_fail > self.recovery_timeout: self.open_circuits.discard(tool) return True return False def record_success(self, tool: str): """Record successful execution""" self.failures[tool] = 0 self.open_circuits.discard(tool) def record_failure(self, tool: str): """Record failed execution""" self.failures[tool] = self.failures.get(tool, 0) + 1 self.last_failure[tool] = time.time() if self.failures[tool] >= self.failure_threshold: self.open_circuits.add(tool) class Harness: """ Uni-Wizard v4 Unified Harness. Single API for all execution needs. """ def __init__( self, house: House = House.TIMMY, mode: Mode = Mode.INTELLIGENT, enable_learning: bool = True, max_workers: int = 4 ): self.house = house self.mode = mode self.enable_learning = enable_learning # Components self.registry = ToolRegistry() self.intelligence = IntelligenceLayer() if mode != Mode.SIMPLE else None self.circuit_breaker = CircuitBreaker() self.executor = ThreadPoolExecutor(max_workers=max_workers) # Metrics self.execution_count = 0 self.success_count = 0 # Register built-in tools self._register_builtin_tools() def _register_builtin_tools(self): """Register built-in tools""" # System tools self.registry.register("system_info", self._system_info) self.registry.register("health_check", self._health_check) # Git tools self.registry.register("git_status", self._git_status) self.registry.register("git_log", self._git_log) # Placeholder for actual implementations self.registry.register("file_read", self._not_implemented) self.registry.register("file_write", self._not_implemented) def _system_info(self, **params) -> Dict: """Get system information""" import platform return { "platform": platform.platform(), "python": platform.python_version(), "processor": platform.processor(), "hostname": platform.node() } def _health_check(self, **params) -> Dict: """Health check""" return { "status": "healthy", "executions": self.execution_count, "success_rate": self.success_count / max(1, self.execution_count) } def _git_status(self, repo_path: str = ".", **params) -> Dict: """Git status (placeholder)""" # Would call actual git command return {"status": "clean", "repo": repo_path} def _git_log(self, repo_path: str = ".", max_count: int = 10, **params) -> Dict: """Git log (placeholder)""" return {"commits": [], "repo": repo_path} def _not_implemented(self, **params) -> Dict: """Placeholder for unimplemented tools""" return {"error": "Tool not yet implemented"} def predict(self, tool: str, params: Dict = None) -> Optional[Prediction]: """Predict execution outcome""" if self.mode == Mode.SIMPLE or not self.intelligence: return None return self.intelligence.predict(tool, self.house.value, params or {}) def execute(self, tool: str, **params) -> ExecutionResult: """ Execute a tool with full v4 capabilities. Flow: 1. Check circuit breaker 2. Get prediction (if intelligent mode) 3. Execute with timeout 4. Record outcome (if learning enabled) 5. Return result with full provenance """ start_time = time.time() started_at = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()) # 1. Circuit breaker check if not self.circuit_breaker.can_execute(tool): return ExecutionResult( success=False, data=None, error=f"Circuit breaker open for {tool}", provenance=Provenance( house=self.house.value, tool=tool, mode=self.mode.value, started_at=started_at, circuit_open=True ), suggestions=[f"Wait for circuit recovery or use alternative tool"] ) # 2. Get prediction prediction = None if self.mode != Mode.SIMPLE: prediction = self.predict(tool, params) # 3. Execute handler = self.registry.get(tool) if not handler: return ExecutionResult( success=False, data=None, error=f"Tool '{tool}' not found", provenance=Provenance( house=self.house.value, tool=tool, mode=self.mode.value, started_at=started_at, prediction=prediction ) ) try: # Execute with timeout for production result_data = handler(**params) success = True error = None self.circuit_breaker.record_success(tool) except Exception as e: success = False error = str(e) result_data = None self.circuit_breaker.record_failure(tool) execution_time_ms = (time.time() - start_time) * 1000 completed_at = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()) # 4. Record for learning if self.enable_learning and self.intelligence: self.intelligence.record(tool, self.house.value, success, execution_time_ms) # Update metrics self.execution_count += 1 if success: self.success_count += 1 # Build provenance input_hash = hashlib.sha256( json.dumps(params, sort_keys=True).encode() ).hexdigest()[:16] output_hash = hashlib.sha256( json.dumps(result_data, default=str).encode() ).hexdigest()[:16] if result_data else "" provenance = Provenance( house=self.house.value, tool=tool, mode=self.mode.value, started_at=started_at, completed_at=completed_at, input_hash=input_hash, output_hash=output_hash, prediction=prediction, execution_time_ms=execution_time_ms ) # Build suggestions suggestions = [] if not success: suggestions.append(f"Check tool availability and parameters") if prediction and prediction.success_rate < 0.5: suggestions.append(f"Low historical success rate - consider alternative approach") return ExecutionResult( success=success, data=result_data, error=error, provenance=provenance, suggestions=suggestions ) async def execute_async(self, tool: str, **params) -> ExecutionResult: """Async execution""" loop = asyncio.get_event_loop() return await loop.run_in_executor(self.executor, self.execute, tool, **params) def execute_batch(self, tasks: List[Dict]) -> List[ExecutionResult]: """ Execute multiple tasks. tasks: [{"tool": "name", "params": {...}}, ...] """ results = [] for task in tasks: result = self.execute(task["tool"], **task.get("params", {})) results.append(result) # In SOVEREIGN mode, stop on first failure if self.mode == Mode.SOVEREIGN and not result.success: break return results def get_stats(self) -> Dict: """Get harness statistics""" return { "house": self.house.value, "mode": self.mode.value, "executions": self.execution_count, "successes": self.success_count, "success_rate": self.success_count / max(1, self.execution_count), "tools_registered": len(self.registry.list_tools()), "learning_enabled": self.enable_learning, "circuit_breaker_open": len(self.circuit_breaker.open_circuits) } def get_patterns(self) -> Dict: """Get learned patterns""" if not self.intelligence: return {} return self.intelligence.patterns # Convenience factory functions def get_harness(house: str = "timmy", mode: str = "intelligent") -> Harness: """Get configured harness""" return Harness( house=House(house), mode=Mode(mode) ) def get_simple_harness() -> Harness: """Get simple harness (no intelligence overhead)""" return Harness(mode=Mode.SIMPLE) def get_intelligent_harness(house: str = "timmy") -> Harness: """Get intelligent harness with learning""" return Harness( house=House(house), mode=Mode.INTELLIGENT, enable_learning=True ) def get_sovereign_harness() -> Harness: """Get sovereign harness (full provenance)""" return Harness( house=House.TIMMY, mode=Mode.SOVEREIGN, enable_learning=True ) # CLI interface if __name__ == "__main__": import argparse parser = argparse.ArgumentParser(description="Uni-Wizard v4") parser.add_argument("--house", default="timmy", choices=["timmy", "ezra", "bezalel", "allegro"]) parser.add_argument("--mode", default="intelligent", choices=["simple", "intelligent", "sovereign"]) parser.add_argument("tool", help="Tool to execute") parser.add_argument("--params", default="{}", help="JSON params") args = parser.parse_args() harness = Harness(house=House(args.house), mode=Mode(args.mode)) params = json.loads(args.params) result = harness.execute(args.tool, **params) print(result.to_json())