| 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_dotenv() |
|
|
| |
| 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") |
| |
| |
| 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: |
| |
| text = result[0].get('generated_text', '') |
| |
| try: |
| |
| 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 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 |
|
|
| |
| workflow = StateGraph(State) |
|
|
| |
| 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) |
|
|
| |
| workflow.add_edge("style", "security") |
| workflow.add_edge("security", "performance") |
| workflow.add_edge("performance", "architecture") |
| workflow.add_edge("architecture", "recommendations") |
|
|
| |
| workflow.set_entry_point("style") |
| workflow.set_finish_point("recommendations") |
|
|
| |
| 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) |
|
|
| |
| 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() |