Spaces:
Runtime error
Runtime error
| import gradio as gr | |
| from langgraph.graph import StateGraph | |
| from typing import TypedDict, Annotated, List, Dict | |
| from langgraph.graph.message import add_messages | |
| from langchain_core.messages import SystemMessage, HumanMessage, AIMessage | |
| import json | |
| import requests | |
| import os | |
| from dotenv import load_dotenv | |
| import time | |
| # Load environment variables | |
| load_dotenv() | |
| # Define the state structure | |
| class State(TypedDict): | |
| messages: Annotated[list[SystemMessage | HumanMessage | AIMessage], add_messages] | |
| current_step: str | |
| code: str | |
| style_analysis: Dict | |
| security_analysis: Dict | |
| performance_analysis: Dict | |
| architecture_analysis: Dict | |
| final_recommendations: Dict | |
| def call_huggingface_api(prompt: str, max_retries=3) -> Dict: | |
| """Call Hugging Face API with retry logic and proper error handling.""" | |
| api_key = os.getenv("HUGGINGFACE_API_KEY") | |
| if not api_key: | |
| raise ValueError("HUGGINGFACE_API_KEY not found in environment variables") | |
| # You can change this to any model you prefer | |
| API_URL = "https://api-inference.huggingface.co/models/mistralai/Mixtral-8x7B-Instruct-v0.1" | |
| headers = {"Authorization": f"Bearer {api_key}"} | |
| for attempt in range(max_retries): | |
| try: | |
| response = requests.post( | |
| API_URL, | |
| headers=headers, | |
| json={ | |
| "inputs": prompt, | |
| "parameters": { | |
| "max_new_tokens": 1000, | |
| "temperature": 0.7, | |
| "top_p": 0.95, | |
| "return_full_text": False | |
| } | |
| } | |
| ) | |
| if response.status_code == 200: | |
| result = response.json() | |
| if isinstance(result, list) and len(result) > 0: | |
| # Extract the generated text | |
| text = result[0].get('generated_text', '') | |
| # Try to parse as JSON if it contains JSON | |
| try: | |
| # Find JSON content between triple backticks if present | |
| if "```json" in text: | |
| json_str = text.split("```json")[1].split("```")[0].strip() | |
| else: | |
| json_str = text.strip() | |
| return json.loads(json_str) | |
| except json.JSONDecodeError: | |
| return {"error": "Failed to parse JSON from response", "raw_text": text} | |
| # If model is loading, wait and retry | |
| if response.status_code == 503: | |
| wait_time = 2 ** attempt | |
| time.sleep(wait_time) | |
| continue | |
| except Exception as e: | |
| if attempt == max_retries - 1: | |
| return {"error": f"API call failed: {str(e)}"} | |
| time.sleep(2 ** attempt) | |
| return {"error": "Maximum retries reached"} | |
| def analyze_code_style(state: State) -> dict: | |
| """Analyze code style and best practices.""" | |
| code = state["code"] | |
| prompt = f"""You are a senior code reviewer focused on code style and best practices. Analyze this code: | |
| {code} | |
| Focus on: | |
| 1. Code readability and clarity | |
| 2. Adherence to common style guides | |
| 3. Variable/function naming | |
| 4. Code organization | |
| 5. Documentation quality | |
| Provide your response in JSON format with these exact keys: | |
| {{ | |
| "issues": ["list of identified style issues"], | |
| "suggestions": ["list of improvement suggestions"], | |
| "overall_rating": "1-10 score as a number", | |
| "primary_concerns": ["list of main style concerns"] | |
| }}""" | |
| analysis = call_huggingface_api(prompt) | |
| if "error" in analysis: | |
| analysis = { | |
| "issues": ["Error analyzing code style"], | |
| "suggestions": ["Try again later"], | |
| "overall_rating": 0, | |
| "primary_concerns": ["Analysis failed"] | |
| } | |
| messages = state["messages"] + [AIMessage(content="Completed code style analysis")] | |
| return {**state, "messages": messages, "style_analysis": analysis, "current_step": "security"} | |
| def analyze_security(state: State) -> dict: | |
| """Analyze security vulnerabilities.""" | |
| code = state["code"] | |
| prompt = f"""You are a security expert. Analyze this code for security vulnerabilities: | |
| {code} | |
| Focus on: | |
| 1. Input validation | |
| 2. Authentication/Authorization | |
| 3. Data exposure | |
| 4. Common vulnerabilities | |
| 5. Security best practices | |
| Provide your response in JSON format with these exact keys: | |
| {{ | |
| "vulnerabilities": ["list of potential security issues"], | |
| "risk_levels": {{"vulnerability": "risk level"}}, | |
| "recommendations": ["list of security improvements"], | |
| "overall_security_score": "1-10 score as a number" | |
| }}""" | |
| analysis = call_huggingface_api(prompt) | |
| if "error" in analysis: | |
| analysis = { | |
| "vulnerabilities": ["Error analyzing security"], | |
| "risk_levels": {"Error": "High"}, | |
| "recommendations": ["Try again later"], | |
| "overall_security_score": 0 | |
| } | |
| messages = state["messages"] + [AIMessage(content="Completed security analysis")] | |
| return {**state, "messages": messages, "security_analysis": analysis, "current_step": "performance"} | |
| def analyze_performance(state: State) -> dict: | |
| """Analyze code performance.""" | |
| code = state["code"] | |
| prompt = f"""You are a performance optimization expert. Analyze this code for performance issues: | |
| {code} | |
| Focus on: | |
| 1. Time complexity | |
| 2. Space complexity | |
| 3. Resource usage | |
| 4. Bottlenecks | |
| 5. Optimization opportunities | |
| Provide your response in JSON format with these exact keys: | |
| {{ | |
| "bottlenecks": ["list of identified performance bottlenecks"], | |
| "complexity_analysis": {{ | |
| "time_complexity": "Big O notation", | |
| "space_complexity": "Big O notation", | |
| "critical_sections": ["list of critical sections"] | |
| }}, | |
| "optimization_suggestions": ["list of performance improvements"], | |
| "performance_score": "1-10 score as a number" | |
| }}""" | |
| analysis = call_huggingface_api(prompt) | |
| if "error" in analysis: | |
| analysis = { | |
| "bottlenecks": ["Error analyzing performance"], | |
| "complexity_analysis": { | |
| "time_complexity": "Unknown", | |
| "space_complexity": "Unknown", | |
| "critical_sections": [] | |
| }, | |
| "optimization_suggestions": ["Try again later"], | |
| "performance_score": 0 | |
| } | |
| messages = state["messages"] + [AIMessage(content="Completed performance analysis")] | |
| return {**state, "messages": messages, "performance_analysis": analysis, "current_step": "architecture"} | |
| def analyze_architecture(state: State) -> dict: | |
| """Analyze code architecture patterns.""" | |
| code = state["code"] | |
| prompt = f"""You are a software architect. Analyze this code's architectural patterns: | |
| {code} | |
| Focus on: | |
| 1. Design patterns used | |
| 2. Code modularity | |
| 3. Component relationships | |
| 4. Architectural anti-patterns | |
| 5. System design principles | |
| Provide your response in JSON format with these exact keys: | |
| {{ | |
| "patterns_identified": ["list of design patterns found"], | |
| "architectural_issues": ["list of architectural concerns"], | |
| "improvement_suggestions": ["list of architectural improvements"], | |
| "architecture_score": "1-10 score as a number" | |
| }}""" | |
| analysis = call_huggingface_api(prompt) | |
| if "error" in analysis: | |
| analysis = { | |
| "patterns_identified": ["Error analyzing architecture"], | |
| "architectural_issues": ["Analysis failed"], | |
| "improvement_suggestions": ["Try again later"], | |
| "architecture_score": 0 | |
| } | |
| messages = state["messages"] + [AIMessage(content="Completed architecture analysis")] | |
| return {**state, "messages": messages, "architecture_analysis": analysis, "current_step": "recommendations"} | |
| def generate_final_recommendations(state: State) -> dict: | |
| """Generate final recommendations based on all analyses.""" | |
| code = state["code"] | |
| prompt = f"""Analyze all previous results and provide final recommendations for this code: | |
| Style Analysis: {json.dumps(state.get('style_analysis', {}))} | |
| Security Analysis: {json.dumps(state.get('security_analysis', {}))} | |
| Performance Analysis: {json.dumps(state.get('performance_analysis', {}))} | |
| Architecture Analysis: {json.dumps(state.get('architecture_analysis', {}))} | |
| Provide your response in JSON format with these exact keys: | |
| {{ | |
| "critical_issues": ["list of most critical issues"], | |
| "priority_improvements": ["list of high-priority improvements"], | |
| "quick_wins": ["list of easy-to-implement improvements"], | |
| "long_term_suggestions": ["list of long-term improvements"], | |
| "overall_health_score": "1-10 score as a number" | |
| }}""" | |
| recommendations = call_huggingface_api(prompt) | |
| if "error" in recommendations: | |
| recommendations = { | |
| "critical_issues": ["Error generating recommendations"], | |
| "priority_improvements": ["Try again later"], | |
| "quick_wins": [], | |
| "long_term_suggestions": [], | |
| "overall_health_score": 0 | |
| } | |
| messages = state["messages"] + [AIMessage(content="Generated final recommendations")] | |
| return {**state, "messages": messages, "final_recommendations": recommendations, "current_step": "end"} | |
| def format_output(state: State) -> str: | |
| """Format the analysis results into a readable output.""" | |
| output = """π Code Analysis Report | |
| π¨ Style & Best Practices | |
| """ | |
| style = state.get("style_analysis", {}) | |
| output += f"Rating: {style.get('overall_rating', 'N/A')}/10\n" | |
| output += "Issues:\n" + "\n".join([f"β’ {issue}" for issue in style.get("issues", [])]) + "\n\n" | |
| output += """π Security Analysis | |
| """ | |
| security = state.get("security_analysis", {}) | |
| output += f"Score: {security.get('overall_security_score', 'N/A')}/10\n" | |
| vulnerabilities = security.get("vulnerabilities", []) | |
| risk_levels = security.get("risk_levels", {}) | |
| output += "Vulnerabilities:\n" + "\n".join([f"β’ {v} ({risk_levels.get(v, 'Unknown')})" for v in vulnerabilities]) + "\n\n" | |
| output += """β‘ Performance Analysis | |
| """ | |
| perf = state.get("performance_analysis", {}) | |
| output += f"Score: {perf.get('performance_score', 'N/A')}/10\n" | |
| output += "Bottlenecks:\n" + "\n".join([f"β’ {b}" for b in perf.get("bottlenecks", [])]) + "\n\n" | |
| output += """ποΈ Architecture Analysis | |
| """ | |
| arch = state.get("architecture_analysis", {}) | |
| output += f"Score: {arch.get('architecture_score', 'N/A')}/10\n" | |
| output += "Patterns:\n" + "\n".join([f"β’ {p}" for p in arch.get("patterns_identified", [])]) + "\n\n" | |
| output += """π Final Recommendations | |
| """ | |
| final = state.get("final_recommendations", {}) | |
| output += f"Overall Health Score: {final.get('overall_health_score', 'N/A')}/10\n\n" | |
| output += "Critical Issues:\n" + "\n".join([f"β’ {i}" for i in final.get("critical_issues", [])]) + "\n\n" | |
| output += "Priority Improvements:\n" + "\n".join([f"β’ {i}" for i in final.get("priority_improvements", [])]) | |
| return output | |
| # Create and setup graph | |
| workflow = StateGraph(State) | |
| # Add nodes | |
| workflow.add_node("style", analyze_code_style) | |
| workflow.add_node("security", analyze_security) | |
| workflow.add_node("performance", analyze_performance) | |
| workflow.add_node("architecture", analyze_architecture) | |
| workflow.add_node("recommendations", generate_final_recommendations) | |
| # Add edges | |
| workflow.add_edge("style", "security") | |
| workflow.add_edge("security", "performance") | |
| workflow.add_edge("performance", "architecture") | |
| workflow.add_edge("architecture", "recommendations") | |
| # Set entry and finish points | |
| workflow.set_entry_point("style") | |
| workflow.set_finish_point("recommendations") | |
| # Compile the workflow | |
| agent = workflow.compile() | |
| def analyze_code(code: str) -> str: | |
| """Analyze the provided code using multiple perspectives.""" | |
| initial_state = State( | |
| messages=[SystemMessage(content="Starting code analysis...")], | |
| current_step="style", | |
| code=code, | |
| style_analysis={}, | |
| security_analysis={}, | |
| performance_analysis={}, | |
| architecture_analysis={}, | |
| final_recommendations={} | |
| ) | |
| final_state = agent.invoke(initial_state) | |
| return format_output(final_state) | |
| # Create Gradio interface | |
| iface = gr.Interface( | |
| fn=analyze_code, | |
| inputs=gr.Code( | |
| label="Enter your code for analysis", | |
| language="python", | |
| lines=20 | |
| ), | |
| outputs=gr.Textbox( | |
| label="Analysis Results", | |
| lines=25 | |
| ), | |
| title="π Code Architecture Critic", | |
| description="Paste your code to get a comprehensive analysis of style, security, performance, and architecture.", | |
| examples=[ | |
| ['''def process_data(data): | |
| result = [] | |
| for i in range(len(data)): | |
| for j in range(len(data)): | |
| if data[i] + data[j] == 10: | |
| result.append((data[i], data[j])) | |
| return result | |
| def save_to_db(user_input): | |
| query = "INSERT INTO users VALUES ('" + user_input + "')" | |
| db.execute(query) | |
| API_KEY = "sk_test_123456789"'''] | |
| ], | |
| theme=gr.themes.Soft() | |
| ) | |
| if __name__ == "__main__": | |
| iface.launch() |