import json import time from pr.autonomous import run_autonomous_mode from pr.core.api import list_models from pr.tools import read_file from pr.tools.base import get_tools_definition from pr.ui import Colors def handle_command(assistant, command): command_parts = command.strip().split(maxsplit=1) cmd = command_parts[0].lower() if cmd == "/auto": if len(command_parts) < 2: print(f"{Colors.RED}Usage: /auto [task description]{Colors.RESET}") print( f"{Colors.GRAY}Example: /auto Create a Python web scraper for news sites{Colors.RESET}" ) return True task = command_parts[1] run_autonomous_mode(assistant, task) return True if cmd in ["exit", "quit", "q"]: return False elif cmd == "help": print( f""" {Colors.BOLD}Available Commands:{Colors.RESET} {Colors.BOLD}Basic:{Colors.RESET} exit, quit, q - Exit the assistant /help - Show this help message /reset - Clear message history /dump - Show message history as JSON /verbose - Toggle verbose mode /models - List available models /tools - List available tools {Colors.BOLD}File Operations:{Colors.RESET} /review - Review a file /refactor - Refactor code in a file /obfuscate - Obfuscate code in a file {Colors.BOLD}Advanced Features:{Colors.RESET} {Colors.CYAN}/auto {Colors.RESET} - Enter autonomous mode {Colors.CYAN}/workflow {Colors.RESET} - Execute a workflow {Colors.CYAN}/workflows{Colors.RESET} - List all workflows {Colors.CYAN}/agent {Colors.RESET} - Create specialized agent and assign task {Colors.CYAN}/agents{Colors.RESET} - Show active agents {Colors.CYAN}/collaborate {Colors.RESET} - Use multiple agents to collaborate {Colors.CYAN}/knowledge {Colors.RESET} - Search knowledge base {Colors.CYAN}/remember {Colors.RESET} - Store information in knowledge base {Colors.CYAN}/history{Colors.RESET} - Show conversation history {Colors.CYAN}/cache{Colors.RESET} - Show cache statistics {Colors.CYAN}/cache clear{Colors.RESET} - Clear all caches {Colors.CYAN}/stats{Colors.RESET} - Show system statistics """ ) elif cmd == "/reset": assistant.messages = assistant.messages[:1] print(f"{Colors.GREEN}Message history cleared{Colors.RESET}") elif cmd == "/dump": print(json.dumps(assistant.messages, indent=2)) elif cmd == "/verbose": assistant.verbose = not assistant.verbose print( f"Verbose mode: {Colors.GREEN if assistant.verbose else Colors.RED}{'ON' if assistant.verbose else 'OFF'}{Colors.RESET}" ) elif cmd.startswith("/model"): if len(command_parts) < 2: print("Current model: " + Colors.GREEN + assistant.model + Colors.RESET) else: assistant.model = command_parts[1] print(f"Model set to: {Colors.GREEN}{assistant.model}{Colors.RESET}") elif cmd == "/models": models = list_models(assistant.model_list_url, assistant.api_key) if isinstance(models, dict) and "error" in models: print(f"{Colors.RED}Error fetching models: {models['error']}{Colors.RESET}") else: print(f"{Colors.BOLD}Available Models:{Colors.RESET}") for model in models: print(f" • {Colors.CYAN}{model['id']}{Colors.RESET}") elif cmd == "/tools": print(f"{Colors.BOLD}Available Tools:{Colors.RESET}") for tool in get_tools_definition(): func = tool["function"] print( f" • {Colors.CYAN}{func['name']}{Colors.RESET}: {func['description']}" ) elif cmd == "/review" and len(command_parts) > 1: filename = command_parts[1] review_file(assistant, filename) elif cmd == "/refactor" and len(command_parts) > 1: filename = command_parts[1] refactor_file(assistant, filename) elif cmd == "/obfuscate" and len(command_parts) > 1: filename = command_parts[1] obfuscate_file(assistant, filename) elif cmd == "/workflows": show_workflows(assistant) elif cmd == "/workflow" and len(command_parts) > 1: workflow_name = command_parts[1] execute_workflow_command(assistant, workflow_name) elif cmd == "/agent" and len(command_parts) > 1: args = command_parts[1].split(maxsplit=1) if len(args) < 2: print(f"{Colors.RED}Usage: /agent {Colors.RESET}") print( f"{Colors.GRAY}Available roles: coding, research, data_analysis, planning, testing, documentation{Colors.RESET}" ) else: role, task = args[0], args[1] execute_agent_task(assistant, role, task) elif cmd == "/agents": show_agents(assistant) elif cmd == "/collaborate" and len(command_parts) > 1: task = command_parts[1] collaborate_agents_command(assistant, task) elif cmd == "/knowledge" and len(command_parts) > 1: query = command_parts[1] search_knowledge(assistant, query) elif cmd == "/remember" and len(command_parts) > 1: content = command_parts[1] store_knowledge(assistant, content) elif cmd == "/history": show_conversation_history(assistant) elif cmd == "/cache": if len(command_parts) > 1 and command_parts[1].lower() == "clear": clear_caches(assistant) else: show_cache_stats(assistant) elif cmd == "/stats": show_system_stats(assistant) elif cmd.startswith("/bg"): handle_background_command(assistant, command) else: return None return True def review_file(assistant, filename): result = read_file(filename) if result["status"] == "success": message = ( f"Please review this file and provide feedback:\n\n{result['content']}" ) from pr.core.assistant import process_message process_message(assistant, message) else: print(f"{Colors.RED}Error reading file: {result['error']}{Colors.RESET}") def refactor_file(assistant, filename): result = read_file(filename) if result["status"] == "success": message = ( f"Please refactor this code to improve its quality:\n\n{result['content']}" ) from pr.core.assistant import process_message process_message(assistant, message) else: print(f"{Colors.RED}Error reading file: {result['error']}{Colors.RESET}") def obfuscate_file(assistant, filename): result = read_file(filename) if result["status"] == "success": message = f"Please obfuscate this code:\n\n{result['content']}" from pr.core.assistant import process_message process_message(assistant, message) else: print(f"{Colors.RED}Error reading file: {result['error']}{Colors.RESET}") def show_workflows(assistant): if not hasattr(assistant, "enhanced"): print(f"{Colors.YELLOW}Enhanced features not initialized{Colors.RESET}") return workflows = assistant.enhanced.get_workflow_list() if not workflows: print(f"{Colors.YELLOW}No workflows found{Colors.RESET}") return print(f"\n{Colors.BOLD}Available Workflows:{Colors.RESET}") for wf in workflows: print(f" • {Colors.CYAN}{wf['name']}{Colors.RESET}: {wf['description']}") print(f" Executions: {wf['execution_count']}") def execute_workflow_command(assistant, workflow_name): if not hasattr(assistant, "enhanced"): print(f"{Colors.YELLOW}Enhanced features not initialized{Colors.RESET}") return print(f"{Colors.YELLOW}Executing workflow: {workflow_name}...{Colors.RESET}") result = assistant.enhanced.execute_workflow(workflow_name) if "error" in result: print(f"{Colors.RED}Error: {result['error']}{Colors.RESET}") else: print(f"{Colors.GREEN}Workflow completed successfully{Colors.RESET}") print(f"Execution ID: {result['execution_id']}") print(f"Results: {json.dumps(result['results'], indent=2)}") def execute_agent_task(assistant, role, task): if not hasattr(assistant, "enhanced"): print(f"{Colors.YELLOW}Enhanced features not initialized{Colors.RESET}") return print(f"{Colors.YELLOW}Creating {role} agent...{Colors.RESET}") agent_id = assistant.enhanced.create_agent(role) print(f"{Colors.GREEN}Agent created: {agent_id}{Colors.RESET}") print(f"{Colors.YELLOW}Executing task...{Colors.RESET}") result = assistant.enhanced.agent_task(agent_id, task) if "error" in result: print(f"{Colors.RED}Error: {result['error']}{Colors.RESET}") else: print(f"\n{Colors.GREEN}{role.capitalize()} Agent Response:{Colors.RESET}") print(result["response"]) def show_agents(assistant): if not hasattr(assistant, "enhanced"): print(f"{Colors.YELLOW}Enhanced features not initialized{Colors.RESET}") return summary = assistant.enhanced.get_agent_summary() print(f"\n{Colors.BOLD}Agent Session Summary:{Colors.RESET}") print(f"Active agents: {summary['active_agents']}") if summary["agents"]: for agent in summary["agents"]: print(f"\n • {Colors.CYAN}{agent['agent_id']}{Colors.RESET}") print(f" Role: {agent['role']}") print(f" Tasks completed: {agent['task_count']}") print(f" Messages: {agent['message_count']}") def collaborate_agents_command(assistant, task): if not hasattr(assistant, "enhanced"): print(f"{Colors.YELLOW}Enhanced features not initialized{Colors.RESET}") return print(f"{Colors.YELLOW}Initiating agent collaboration...{Colors.RESET}") roles = ["coding", "research", "planning"] result = assistant.enhanced.collaborate_agents(task, roles) print(f"\n{Colors.GREEN}Collaboration completed{Colors.RESET}") print(f"\nOrchestrator response:") if "orchestrator" in result and "response" in result["orchestrator"]: print(result["orchestrator"]["response"]) if result.get("agents"): print(f"\n{Colors.BOLD}Agent Results:{Colors.RESET}") for agent_result in result["agents"]: if "role" in agent_result: print(f"\n{Colors.CYAN}{agent_result['role']}:{Colors.RESET}") print(agent_result.get("response", "No response")) def search_knowledge(assistant, query): if not hasattr(assistant, "enhanced"): print(f"{Colors.YELLOW}Enhanced features not initialized{Colors.RESET}") return results = assistant.enhanced.search_knowledge(query) if not results: print(f"{Colors.YELLOW}No knowledge entries found for: {query}{Colors.RESET}") return print(f"\n{Colors.BOLD}Knowledge Search Results:{Colors.RESET}") for entry in results: print(f"\n • {Colors.CYAN}[{entry.category}]{Colors.RESET}") print(f" {entry.content[:200]}...") print(f" Accessed: {entry.access_count} times") def store_knowledge(assistant, content): if not hasattr(assistant, "enhanced"): print(f"{Colors.YELLOW}Enhanced features not initialized{Colors.RESET}") return import time import uuid from pr.memory import KnowledgeEntry categories = assistant.enhanced.fact_extractor.categorize_content(content) entry_id = str(uuid.uuid4())[:16] entry = KnowledgeEntry( entry_id=entry_id, category=categories[0] if categories else "general", content=content, metadata={"manual_entry": True}, created_at=time.time(), updated_at=time.time(), ) assistant.enhanced.knowledge_store.add_entry(entry) print(f"{Colors.GREEN}Knowledge stored successfully{Colors.RESET}") print(f"Entry ID: {entry_id}") print(f"Category: {entry.category}") def show_conversation_history(assistant): if not hasattr(assistant, "enhanced"): print(f"{Colors.YELLOW}Enhanced features not initialized{Colors.RESET}") return history = assistant.enhanced.get_conversation_history(limit=10) if not history: print(f"{Colors.YELLOW}No conversation history found{Colors.RESET}") return print(f"\n{Colors.BOLD}Recent Conversations:{Colors.RESET}") for conv in history: import datetime started = datetime.datetime.fromtimestamp(conv["started_at"]).strftime( "%Y-%m-%d %H:%M" ) print(f"\n • {Colors.CYAN}{conv['conversation_id']}{Colors.RESET}") print(f" Started: {started}") print(f" Messages: {conv['message_count']}") if conv.get("summary"): print(f" Summary: {conv['summary'][:100]}...") if conv.get("topics"): print(f" Topics: {', '.join(conv['topics'])}") def show_cache_stats(assistant): if not hasattr(assistant, "enhanced"): print(f"{Colors.YELLOW}Enhanced features not initialized{Colors.RESET}") return stats = assistant.enhanced.get_cache_statistics() print(f"\n{Colors.BOLD}Cache Statistics:{Colors.RESET}") if "api_cache" in stats: api_stats = stats["api_cache"] print(f"\n{Colors.CYAN}API Cache:{Colors.RESET}") print(f" Total entries: {api_stats['total_entries']}") print(f" Valid entries: {api_stats['valid_entries']}") print(f" Expired entries: {api_stats['expired_entries']}") print(f" Cached tokens: {api_stats['total_cached_tokens']}") if "tool_cache" in stats: tool_stats = stats["tool_cache"] print(f"\n{Colors.CYAN}Tool Cache:{Colors.RESET}") print(f" Total entries: {tool_stats['total_entries']}") print(f" Valid entries: {tool_stats['valid_entries']}") print(f" Total cache hits: {tool_stats['total_cache_hits']}") if tool_stats.get("by_tool"): print(f"\n Per-tool statistics:") for tool_name, tool_stat in tool_stats["by_tool"].items(): print( f" {tool_name}: {tool_stat['cached_entries']} entries, {tool_stat['total_hits']} hits" ) def clear_caches(assistant): if not hasattr(assistant, "enhanced"): print(f"{Colors.YELLOW}Enhanced features not initialized{Colors.RESET}") return assistant.enhanced.clear_caches() print(f"{Colors.GREEN}All caches cleared successfully{Colors.RESET}") def show_system_stats(assistant): if not hasattr(assistant, "enhanced"): print(f"{Colors.YELLOW}Enhanced features not initialized{Colors.RESET}") return print(f"\n{Colors.BOLD}System Statistics:{Colors.RESET}") cache_stats = assistant.enhanced.get_cache_statistics() knowledge_stats = assistant.enhanced.get_knowledge_statistics() agent_summary = assistant.enhanced.get_agent_summary() print(f"\n{Colors.CYAN}Knowledge Base:{Colors.RESET}") print(f" Total entries: {knowledge_stats['total_entries']}") print(f" Categories: {knowledge_stats['total_categories']}") print(f" Total accesses: {knowledge_stats['total_accesses']}") print(f" Vocabulary size: {knowledge_stats['vocabulary_size']}") print(f"\n{Colors.CYAN}Active Agents:{Colors.RESET}") print(f" Count: {agent_summary['active_agents']}") if "api_cache" in cache_stats: print(f"\n{Colors.CYAN}Caching:{Colors.RESET}") print(f" API cache entries: {cache_stats['api_cache']['valid_entries']}") if "tool_cache" in cache_stats: print(f" Tool cache entries: {cache_stats['tool_cache']['valid_entries']}") def handle_background_command(assistant, command): """Handle background multiplexer commands.""" parts = command.strip().split(maxsplit=2) if len(parts) < 2: print(f"{Colors.RED}Usage: /bg [args]{Colors.RESET}") print( f"{Colors.GRAY}Available subcommands: start, list, status, output, input, kill, events{Colors.RESET}" ) return subcmd = parts[1].lower() try: if subcmd == "start" and len(parts) >= 3: session_name = f"bg_{len(parts[2].split())}_{int(time.time())}" start_background_session(assistant, session_name, parts[2]) elif subcmd == "list": list_background_sessions(assistant) elif subcmd == "status" and len(parts) >= 3: show_session_status(assistant, parts[2]) elif subcmd == "output" and len(parts) >= 3: show_session_output(assistant, parts[2]) elif subcmd == "input" and len(parts) >= 4: send_session_input(assistant, parts[2], parts[3]) elif subcmd == "kill" and len(parts) >= 3: kill_background_session(assistant, parts[2]) elif subcmd == "events": show_background_events(assistant) else: print(f"{Colors.RED}Unknown background command: {subcmd}{Colors.RESET}") print( f"{Colors.GRAY}Available: start, list, status, output, input, kill, events{Colors.RESET}" ) except Exception as e: print(f"{Colors.RED}Error executing background command: {e}{Colors.RESET}") def start_background_session(assistant, session_name, command): """Start a command in background.""" try: from pr.multiplexer import start_background_process result = start_background_process(session_name, command) if result["status"] == "success": print( f"{Colors.GREEN}Started background session '{session_name}' with PID {result['pid']}{Colors.RESET}" ) else: print( f"{Colors.RED}Failed to start background session: {result.get('error', 'Unknown error')}{Colors.RESET}" ) except Exception as e: print(f"{Colors.RED}Error starting background session: {e}{Colors.RESET}") def list_background_sessions(assistant): """List all background sessions.""" try: from pr.multiplexer import get_all_sessions from pr.ui.display import display_multiplexer_status sessions = get_all_sessions() display_multiplexer_status(sessions) except Exception as e: print(f"{Colors.RED}Error listing background sessions: {e}{Colors.RESET}") def show_session_status(assistant, session_name): """Show status of a specific session.""" try: from pr.multiplexer import get_session_info info = get_session_info(session_name) if info: print(f"{Colors.BOLD}Session '{session_name}':{Colors.RESET}") print(f" Status: {info.get('status', 'unknown')}") print(f" PID: {info.get('pid', 'N/A')}") print(f" Command: {info.get('command', 'N/A')}") if "start_time" in info: import time elapsed = time.time() - info["start_time"] print(f" Running for: {elapsed:.1f}s") else: print(f"{Colors.YELLOW}Session '{session_name}' not found{Colors.RESET}") except Exception as e: print(f"{Colors.RED}Error getting session status: {e}{Colors.RESET}") def show_session_output(assistant, session_name): """Show output of a specific session.""" try: from pr.multiplexer import get_session_output output = get_session_output(session_name, lines=50) if output: print(f"{Colors.BOLD}Recent output from '{session_name}':{Colors.RESET}") print(f"{Colors.GRAY}{'─' * 60}{Colors.RESET}") for line in output: print(line) else: print( f"{Colors.YELLOW}No output available for session '{session_name}'{Colors.RESET}" ) except Exception as e: print(f"{Colors.RED}Error getting session output: {e}{Colors.RESET}") def send_session_input(assistant, session_name, input_text): """Send input to a background session.""" try: from pr.multiplexer import send_input_to_session result = send_input_to_session(session_name, input_text) if result["status"] == "success": print(f"{Colors.GREEN}Input sent to session '{session_name}'{Colors.RESET}") else: print( f"{Colors.RED}Failed to send input: {result.get('error', 'Unknown error')}{Colors.RESET}" ) except Exception as e: print(f"{Colors.RED}Error sending input: {e}{Colors.RESET}") def kill_background_session(assistant, session_name): """Kill a background session.""" try: from pr.multiplexer import kill_session result = kill_session(session_name) if result["status"] == "success": print(f"{Colors.GREEN}Session '{session_name}' terminated{Colors.RESET}") else: print( f"{Colors.RED}Failed to kill session: {result.get('error', 'Unknown error')}{Colors.RESET}" ) except Exception as e: print(f"{Colors.RED}Error killing session: {e}{Colors.RESET}") def show_background_events(assistant): """Show recent background events.""" try: from pr.core.background_monitor import get_global_monitor monitor = get_global_monitor() events = monitor.get_pending_events() if events: print(f"{Colors.BOLD}Recent Background Events:{Colors.RESET}") print(f"{Colors.GRAY}{'─' * 60}{Colors.RESET}") for event in events[-10:]: # Show last 10 events from pr.ui.display import display_background_event display_background_event(event) else: print(f"{Colors.GRAY}No recent background events{Colors.RESET}") except Exception as e: print(f"{Colors.RED}Error getting background events: {e}{Colors.RESET}")