""" Intelligent Tool Completion and Recommendation Module Provides AI-powered tool recommendations, explanations, and workflow generation. """ from .base import * class IntelligentCompletion(MCPMixin): """Intelligent tool completion and recommendation system 🧠 AI-POWERED RECOMMENDATIONS: - Analyze task descriptions and suggest optimal tool combinations - Context-aware recommendations based on working directory and file types - Performance-optimized tool selection for different use cases - Learning from usage patterns to improve suggestions """ def __init__(self): # Tool categories and their use cases self.tool_categories = { "file_operations": { "tools": [ "file_enhanced_list_directory", "file_tre_directory_tree", "file_list_directory_tree", "file_watch_files", "file_bulk_rename", "file_backup", ], "keywords": [ "list", "directory", "files", "tree", "watch", "rename", "backup", "browse", "explore", ], "use_cases": [ "explore project structure", "monitor file changes", "organize files", "backup important files", ], }, "git_operations": { "tools": ["git_status", "git_diff", "git_grep", "git_commit_prepare"], "keywords": [ "git", "repository", "commit", "diff", "search", "version control", "changes", ], "use_cases": [ "check git status", "search code", "review changes", "prepare commits", ], }, "high_performance_analytics": { "tools": ["sneller_query", "sneller_optimize", "sneller_setup"], "keywords": [ "sql", "query", "analytics", "data", "fast", "performance", "json", "analysis", ], "use_cases": [ "analyze large datasets", "run SQL queries", "optimize performance", "process JSON data", ], }, "terminal_recording": { "tools": [ "asciinema_record", "asciinema_search", "asciinema_playback", "asciinema_auth", "asciinema_upload", "asciinema_config", ], "keywords": ["record", "terminal", "session", "demo", "audit", "playback", "share"], "use_cases": [ "record terminal sessions", "create demos", "audit commands", "share workflows", ], }, "archive_compression": { "tools": [ "archive_create_archive", "archive_extract_archive", "archive_list_archive", "archive_compress_file", ], "keywords": ["archive", "compress", "extract", "zip", "tar", "backup", "package"], "use_cases": [ "create archives", "extract files", "compress data", "package projects", ], }, "development_workflow": { "tools": ["dev_run_tests", "dev_lint_code", "dev_format_code"], "keywords": [ "test", "lint", "format", "code", "quality", "development", "ci", "build", ], "use_cases": [ "run tests", "check code quality", "format code", "development workflow", ], }, "network_api": { "tools": ["net_http_request", "net_api_mock_server"], "keywords": [ "http", "api", "request", "server", "network", "rest", "endpoint", "mock", ], "use_cases": [ "test APIs", "make HTTP requests", "mock services", "network debugging", ], }, } # Performance profiles for different use cases self.performance_profiles = { "speed_critical": ["sneller_query", "git_grep", "file_tre_directory_tree"], "comprehensive_analysis": ["file_list_directory_tree", "git_status", "git_diff"], "automation_friendly": ["file_bulk_rename", "dev_run_tests", "archive_create_archive"], "educational": ["asciinema_record", "asciinema_playback"], } @mcp_tool( name="recommend_tools", description="🧠 Get intelligent tool recommendations for specific tasks", ) async def recommend_tools( self, task_description: str, context: Optional[Dict[str, Any]] = None, working_directory: Optional[str] = None, performance_priority: Optional[ Literal["speed", "comprehensive", "automation", "educational"] ] = "comprehensive", max_recommendations: Optional[int] = 5, include_examples: Optional[bool] = True, ctx: Context = None, ) -> Dict[str, Any]: """Get intelligent recommendations for tools to use for a specific task.""" try: if ctx: await ctx.log_info(f"🧠 Analyzing task: '{task_description}'") # Analyze the task description task_analysis = await self._analyze_task_description( task_description, context, working_directory, ctx ) # Get context information if working directory provided directory_context = {} if working_directory: directory_context = await self._analyze_directory_context(working_directory, ctx) # Generate tool recommendations recommendations = await self._generate_tool_recommendations( task_analysis, directory_context, performance_priority, max_recommendations, ctx ) # Enhance recommendations with examples and explanations enhanced_recommendations = [] for rec in recommendations: enhanced_rec = await self._enhance_recommendation( rec, task_description, include_examples, ctx ) enhanced_recommendations.append(enhanced_rec) # Generate workflow suggestions for complex tasks workflow_suggestions = await self._generate_workflow_suggestions( task_analysis, enhanced_recommendations, ctx ) result = { "task_description": task_description, "task_analysis": task_analysis, "directory_context": directory_context, "recommendations": enhanced_recommendations, "workflow_suggestions": workflow_suggestions, "performance_profile": performance_priority, "total_tools_available": sum( len(cat["tools"]) for cat in self.tool_categories.values() ), "recommendation_confidence": await self._calculate_confidence( task_analysis, enhanced_recommendations ), "alternative_approaches": await self._suggest_alternatives( task_analysis, enhanced_recommendations, ctx ), } if ctx: await ctx.log_info(f"🧠 Generated {len(enhanced_recommendations)} recommendations") return result except Exception as e: error_msg = f"Tool recommendation failed: {str(e)}" if ctx: await ctx.log_error(error_msg) return {"error": error_msg} @mcp_tool( name="explain_tool", description="📚 Get detailed explanation and usage examples for any tool", ) async def explain_tool( self, tool_name: str, include_examples: Optional[bool] = True, include_related_tools: Optional[bool] = True, use_case_focus: Optional[str] = None, ctx: Context = None, ) -> Dict[str, Any]: """Get comprehensive explanation and usage examples for any available tool.""" try: if ctx: await ctx.log_info(f"📚 Explaining tool: {tool_name}") # Find the tool in our categories tool_info = await self._find_tool_info(tool_name) if not tool_info: return { "error": f"Tool '{tool_name}' not found", "suggestion": "Use 'recommend_tools' to discover available tools", "available_categories": list(self.tool_categories.keys()), } # Generate comprehensive explanation explanation = { "tool_name": tool_name, "category": tool_info["category"], "description": tool_info["description"], "primary_use_cases": tool_info["use_cases"], "performance_characteristics": await self._get_performance_characteristics( tool_name ), "best_practices": await self._get_best_practices(tool_name, use_case_focus), } # Add practical examples if include_examples: explanation["examples"] = await self._generate_tool_examples( tool_name, use_case_focus, ctx ) # Add related tools if include_related_tools: explanation["related_tools"] = await self._find_related_tools( tool_name, tool_info["category"] ) explanation["workflow_combinations"] = await self._suggest_tool_combinations( tool_name, ctx ) # Add optimization hints explanation["optimization_hints"] = await self._get_optimization_hints(tool_name) if ctx: await ctx.log_info(f"📚 Generated explanation for {tool_name}") return explanation except Exception as e: error_msg = f"Tool explanation failed: {str(e)}" if ctx: await ctx.log_error(error_msg) return {"error": error_msg} @mcp_tool( name="suggest_workflow", description="🔄 Generate complete workflows for complex multi-step tasks", ) async def suggest_workflow( self, goal_description: str, constraints: Optional[Dict[str, Any]] = None, time_budget: Optional[str] = None, automation_level: Optional[ Literal["manual", "semi-automated", "fully-automated"] ] = "semi-automated", ctx: Context = None, ) -> Dict[str, Any]: """Generate complete multi-step workflows for complex tasks.""" try: if ctx: await ctx.log_info(f"🔄 Designing workflow for: '{goal_description}'") # Break down the goal into steps workflow_steps = await self._break_down_goal(goal_description, constraints, ctx) # Assign tools to each step step_assignments = [] for i, step in enumerate(workflow_steps): step_tools = await self._assign_tools_to_step(step, automation_level, ctx) step_assignments.append( { "step_number": i + 1, "step_description": step["description"], "recommended_tools": step_tools, "estimated_duration": step.get("duration", "5-10 minutes"), "dependencies": step.get("dependencies", []), "automation_potential": step.get("automation", "medium"), } ) # Generate execution plan execution_plan = await self._generate_execution_plan(step_assignments, time_budget, ctx) # Add error handling and fallbacks error_handling = await self._generate_error_handling(step_assignments, ctx) # Generate automation scripts if requested automation_scripts = {} if automation_level in ["semi-automated", "fully-automated"]: automation_scripts = await self._generate_automation_scripts( step_assignments, automation_level, ctx ) workflow = { "goal": goal_description, "total_steps": len(step_assignments), "estimated_total_time": execution_plan.get("total_time", "30-60 minutes"), "automation_level": automation_level, "workflow_steps": step_assignments, "execution_plan": execution_plan, "error_handling": error_handling, "automation_scripts": automation_scripts, "success_criteria": await self._define_success_criteria(goal_description, ctx), "monitoring_suggestions": await self._suggest_monitoring(step_assignments, ctx), } if ctx: await ctx.log_info(f"🔄 Generated {len(step_assignments)}-step workflow") return workflow except Exception as e: error_msg = f"Workflow generation failed: {str(e)}" if ctx: await ctx.log_error(error_msg) return {"error": error_msg} # Helper methods would be implemented here... # For now, implementing stubs to avoid the file being too long async def _analyze_task_description( self, task: str, context: Optional[Dict[str, Any]], working_dir: Optional[str], ctx: Context ) -> Dict[str, Any]: """Analyze task description to understand intent and requirements""" task_lower = task.lower() analysis = { "primary_intent": "unknown", "task_complexity": "medium", "keywords_found": [], "categories_matched": [], "performance_requirements": "standard", "data_types": [], "automation_potential": "medium", } # Analyze for primary intent if any(word in task_lower for word in ["search", "find", "grep", "look"]): analysis["primary_intent"] = "search" elif any(word in task_lower for word in ["analyze", "report", "statistics", "metrics"]): analysis["primary_intent"] = "analysis" elif any(word in task_lower for word in ["record", "capture", "demo", "show"]): analysis["primary_intent"] = "recording" elif any(word in task_lower for word in ["backup", "archive", "save", "compress"]): analysis["primary_intent"] = "backup" elif any(word in task_lower for word in ["list", "show", "display", "explore"]): analysis["primary_intent"] = "exploration" # Match categories for category, info in self.tool_categories.items(): if any(keyword in task_lower for keyword in info["keywords"]): analysis["categories_matched"].append(category) analysis["keywords_found"].extend( [kw for kw in info["keywords"] if kw in task_lower] ) return analysis async def _analyze_directory_context(self, working_dir: str, ctx: Context) -> Dict[str, Any]: """Analyze working directory to provide context-aware recommendations""" context = { "is_git_repo": False, "project_type": "unknown", "file_types": [], "size_estimate": "medium", "special_files": [], } try: # Check if it's a git repository git_check = subprocess.run( ["git", "rev-parse", "--git-dir"], cwd=working_dir, capture_output=True, text=True ) context["is_git_repo"] = git_check.returncode == 0 except Exception: pass # Ignore errors in context analysis return context async def _generate_tool_recommendations( self, task_analysis: Dict[str, Any], directory_context: Dict[str, Any], performance_priority: str, max_recommendations: int, ctx: Context, ) -> List[Dict[str, Any]]: """Generate ranked tool recommendations based on analysis""" recommendations = [] # Score tools based on task analysis for category, info in self.tool_categories.items(): if category in task_analysis["categories_matched"]: for tool in info["tools"]: score = await self._calculate_tool_score( tool, category, task_analysis, directory_context, performance_priority ) recommendations.append( { "tool_name": tool, "category": category, "score": score, "primary_reason": self._get_recommendation_reason( tool, task_analysis, directory_context ), "confidence": min(100, score * 10), # Convert to percentage } ) # Sort by score and return top recommendations recommendations.sort(key=lambda x: x["score"], reverse=True) return recommendations[:max_recommendations] async def _calculate_tool_score( self, tool: str, category: str, task_analysis: Dict[str, Any], directory_context: Dict[str, Any], performance_priority: str, ) -> float: """Calculate relevance score for a tool""" base_score = 5.0 # Base relevance score # Boost score based on keyword matches keywords_matched = len(task_analysis["keywords_found"]) base_score += keywords_matched * 0.5 # Boost based on performance priority if performance_priority == "speed" and tool in self.performance_profiles["speed_critical"]: base_score += 2.0 elif ( performance_priority == "comprehensive" and tool in self.performance_profiles["comprehensive_analysis"] ): base_score += 1.5 # Context-specific boosts if directory_context.get("is_git_repo") and "git" in tool: base_score += 1.0 return min(10.0, base_score) # Cap at 10.0 def _get_recommendation_reason( self, tool: str, task_analysis: Dict[str, Any], directory_context: Dict[str, Any] ) -> str: """Generate human-readable reason for tool recommendation""" reasons = [] if task_analysis.get("primary_intent") == "search" and "grep" in tool: reasons.append("excellent for code search") if directory_context.get("is_git_repo") and "git" in tool: reasons.append("optimized for git repositories") if task_analysis.get("performance_requirements") == "high" and "sneller" in tool: reasons.append("high-performance vectorized processing") if "tre" in tool: reasons.append("LLM-optimized directory tree output") if "asciinema" in tool: reasons.append("terminal recording and sharing") return reasons[0] if reasons else "matches task requirements" # Implement remaining helper methods as stubs for now async def _enhance_recommendation( self, rec: Dict[str, Any], task_description: str, include_examples: bool, ctx: Context ) -> Dict[str, Any]: return rec async def _generate_workflow_suggestions( self, task_analysis: Dict[str, Any], recommendations: List[Dict[str, Any]], ctx: Context ) -> List[Dict[str, str]]: return [] async def _calculate_confidence( self, task_analysis: Dict[str, Any], recommendations: List[Dict[str, Any]] ) -> int: return 75 async def _suggest_alternatives( self, task_analysis: Dict[str, Any], recommendations: List[Dict[str, Any]], ctx: Context ) -> List[str]: return [] async def _find_tool_info(self, tool_name: str) -> Optional[Dict[str, Any]]: for category, info in self.tool_categories.items(): if tool_name in info["tools"]: return { "category": category, "description": f"Tool in {category} category", "use_cases": info["use_cases"], } return None async def _get_performance_characteristics(self, tool_name: str) -> Dict[str, str]: return {"speed": "medium", "memory": "medium", "cpu": "medium"} async def _get_best_practices(self, tool_name: str, use_case_focus: Optional[str]) -> List[str]: return ["Follow tool-specific documentation", "Test with small datasets first"] async def _generate_tool_examples( self, tool_name: str, context: str, ctx: Context ) -> List[Dict[str, str]]: return [] async def _find_related_tools(self, tool_name: str, category: str) -> List[str]: return [] async def _suggest_tool_combinations( self, tool_name: str, ctx: Context ) -> List[Dict[str, str]]: return [] async def _get_optimization_hints(self, tool_name: str) -> List[str]: return [] async def _break_down_goal( self, goal: str, constraints: Optional[Dict[str, Any]], ctx: Context ) -> List[Dict[str, Any]]: return [{"description": "Understand current state", "duration": "10 minutes"}] async def _assign_tools_to_step( self, step: Dict[str, Any], automation_level: str, ctx: Context ) -> List[str]: return ["file_enhanced_list_directory"] async def _generate_execution_plan( self, steps: List[Dict[str, Any]], time_budget: Optional[str], ctx: Context ) -> Dict[str, Any]: return {"total_steps": len(steps), "total_time": "30 minutes"} async def _generate_error_handling( self, steps: List[Dict[str, Any]], ctx: Context ) -> Dict[str, Any]: return {"common_failures": [], "fallback_strategies": [], "recovery_procedures": []} async def _generate_automation_scripts( self, steps: List[Dict[str, Any]], automation_level: str, ctx: Context ) -> Dict[str, str]: return {} async def _define_success_criteria(self, goal: str, ctx: Context) -> List[str]: return ["All workflow steps completed without errors"] async def _suggest_monitoring(self, steps: List[Dict[str, Any]], ctx: Context) -> List[str]: return ["Monitor execution time for each step"]