model_router_cli.py
1 #!/usr/bin/env python3 2 """ 3 Model Router CLI - AI Agent Agnostic interface. 4 5 Treats all AI models the same: 6 python3 scripts/model_router_cli.py "your question" 7 python3 scripts/model_router_cli.py --model gemini-flash "quick question" 8 python3 scripts/model_router_cli.py --status 9 python3 scripts/model_router_cli.py --consensus "important decision" 10 11 The router automatically: 12 - Routes to best available model 13 - Falls back if one fails 14 - Injects Sovereign OS context 15 """ 16 17 import sys 18 import os 19 import json 20 from pathlib import Path 21 22 # Add core to path 23 SOVEREIGN_ROOT = Path(__file__).parent.parent 24 sys.path.insert(0, str(SOVEREIGN_ROOT)) 25 26 from core.mesh import ModelRouter, TaskType 27 28 29 def print_status(router: ModelRouter): 30 """Print router status.""" 31 status = router.status() 32 33 print("\n" + "=" * 60) 34 print("MODEL ROUTER STATUS") 35 print("=" * 60) 36 37 print(f"\nAvailable models: {', '.join(status['available']) or 'NONE'}") 38 print(f"Mesh connected: {status['mesh_connected']}") 39 40 print("\nAdapter Details:") 41 print("-" * 60) 42 43 for name, info in status['adapters'].items(): 44 available = "✓" if info['available'] else "✗" 45 caps = info['capabilities'] 46 print(f" {available} {name}") 47 print(f" coding={caps['coding']:.1f} research={caps['research']:.1f} " 48 f"speed={caps['speed']:.1f} cost={caps['cost_efficiency']:.1f}") 49 print(f" context={caps['context_window']:,} tokens") 50 51 print("\n" + "=" * 60) 52 53 54 def main(): 55 args = sys.argv[1:] 56 57 if not args: 58 print(__doc__) 59 print("\nQuick status check:") 60 router = ModelRouter() 61 available = router.available_models() 62 if available: 63 print(f" Available: {', '.join(available)}") 64 else: 65 print(" No models available. Set GEMINI_API_KEY or ANTHROPIC_API_KEY") 66 return 67 68 router = ModelRouter() 69 70 # Handle flags 71 if args[0] == "--status": 72 print_status(router) 73 return 74 75 if args[0] == "--consensus": 76 if len(args) < 2: 77 print("Usage: --consensus <prompt>") 78 return 79 prompt = " ".join(args[1:]) 80 print("\nQuerying multiple models for consensus...\n") 81 result = router.consensus(prompt) 82 if "error" in result: 83 print(f"Error: {result['error']}") 84 return 85 print(f"Models queried: {', '.join(result['models_queried'])}") 86 print(f"Synthesis: {result['synthesis']}") 87 print("\nIndividual responses:") 88 for model, resp in result['responses'].items(): 89 print(f"\n--- {model} ---") 90 print(resp['content'][:500] + "..." if len(resp['content']) > 500 else resp['content']) 91 return 92 93 # Parse model flag 94 model = None 95 task_type = TaskType.CODING 96 prompt_start = 0 97 98 if args[0] == "--model": 99 if len(args) < 3: 100 print("Usage: --model <model-name> <prompt>") 101 return 102 model = args[1] 103 prompt_start = 2 104 105 if args[prompt_start] == "--research": 106 task_type = TaskType.RESEARCH 107 prompt_start += 1 108 elif args[prompt_start] == "--quick": 109 task_type = TaskType.QUICK 110 prompt_start += 1 111 112 prompt = " ".join(args[prompt_start:]) 113 114 if not prompt: 115 print("Please provide a prompt.") 116 return 117 118 # Query 119 print(f"\nRouting to {'best available' if not model else model}...\n") 120 response = router.query( 121 prompt, 122 task_type=task_type, 123 model=model, 124 ) 125 126 print(f"[{response.model_name}] ({response.latency_ms}ms)") 127 print("-" * 60) 128 print(response.content) 129 130 131 if __name__ == "__main__": 132 main()