| import json | |
| import logging | |
| import re | |
| from langchain_core.messages import SystemMessage, HumanMessage | |
| from core.llm_factory import create_sambanova_llm ,create_openai_llm | |
| class RefactoringAdvisor: | |
| """ | |
| Analyzes project structure and proposes architectural changes (Design Patterns). | |
| """ | |
| def __init__(self, llm=None): | |
| self.llm = llm or create_openai_llm(temperature=0.0) | |
| def propose_improvement(self, structure_data: list[dict]) -> dict: | |
| """ | |
| Analyzes the code and generates a proposal with BEFORE and AFTER UML. | |
| Returns: | |
| { | |
| "title": "Strategy Pattern for Payment Processing", | |
| "description": "Currently, the Payment class uses big if-else...", | |
| "proposed_uml": "@startuml ... @enduml", | |
| "affected_files": ["payment.py", "order.py"] | |
| } | |
| """ | |
| summary = self._summarize_for_llm(structure_data) | |
| logging.info("🧠 Brainstorming architectural improvements...") | |
| prompt = f""" | |
| Act as a Principal Software Architect. | |
| Analyze this Python project structure summary to find ONE critical design flaw. | |
| Current Structure: | |
| {json.dumps(summary, indent=2)} | |
| Your Goal: | |
| 1. Identify the weak spot (High Coupling, Low Cohesion, Violation of SOLID). | |
| 2. Select the BEST Design Pattern to fix it (Factory, Strategy, Observer, Adapter, etc.). | |
| 3. Redesign the affected classes using this pattern. | |
| Output strictly in JSON format: | |
| {{ | |
| "title": "Short title of the refactoring", | |
| "description": "Explanation of the problem and why this pattern solves it", | |
| "affected_classes": ["ClassA", "ClassB"], | |
| "proposed_uml": "The FULL PlantUML code representing the NEW structure for these classes (start with @startuml)" | |
| }} | |
| """ | |
| try: | |
| messages = [ | |
| SystemMessage(content="You are a JSON-only architect assistant."), | |
| HumanMessage(content=prompt) | |
| ] | |
| response = self.llm.invoke(messages) | |
| content = self._clean_json_output(response.content) | |
| return json.loads(content) | |
| except Exception as e: | |
| logging.error(f"Refactoring proposal failed: {e}") | |
| return {"error": str(e)} | |
| def _summarize_for_llm(self, structure: list[dict]): | |
| """Simplifies the structure to save tokens.""" | |
| summary = [] | |
| for item in structure: | |
| if item.get("type") == "module": continue | |
| summary.append({ | |
| "class": item["name"], | |
| "inherits": item["bases"], | |
| "methods": [m["name"] for m in item["methods"]], | |
| "attributes": [a["type"] for a in item["attributes"]] | |
| }) | |
| return summary | |
| def _clean_json_output(self, content: str) -> str: | |
| """Fixes common LLM JSON formatting issues.""" | |
| if "```json" in content: | |
| content = content.split("```json")[1].split("```")[0] | |
| elif "```" in content: | |
| content = content.split("```")[1].split("```")[0] | |
| return content.strip() |