├── README.md ├── codspy.png ├── requirements.txt ├── v1_CoT_CodeLlama.py ├── v2_CoT_Llama.py └── v3_ReAct.py /README.md: -------------------------------------------------------------------------------- 1 | # CoDSPy: AI-Powered Code Optimizer & Reviewer 2 | 3 | [![Python 3.8+](https://img.shields.io/badge/Python-3.8+-blue.svg)](https://www.python.org/) 4 | [![Gradio Interface](https://img.shields.io/badge/Interface-Gradio-FF6B6B.svg)](https://gradio.app/) 5 | 6 | ## 🧙‍♂️ Project Overview 7 | CoDSPy is an intelligent code optimization system that combines AI analysis, automated refactoring, and test generation into a single workflow. Built with DSPy and Gradio, it transforms raw code into optimized, test-covered implementations through **Chain-of-Thought (CoT)** and **ReAct reasoning**. 8 | ![Architecture](codspy.png) 9 | 10 | ## ✨ Key Features 11 | - **AI-Powered Code Analysis**: Detects potential issues using **CoT** and **ReAct reasoning** 12 | - **Smart Optimization**: Suggests and implements code improvements 13 | - **Test Generation**: Creates comprehensive test cases and code 14 | - **Interactive Interface**: Gradio-based web UI with real-time results 15 | - **Local AI Integration**: Runs on Ollama with custom LLM models 16 | - **Multiple Implementations**: Supports both **CoT** and **ReAct** approaches 17 | 18 | ## 🗂️ Project Structure 19 | ``` 20 | . 21 | ├── README.md # Project documentation 22 | ├── testcodes.py # Sample test codes for evaluation 23 | ├── v1_CoT_CodeLlama.py # CoT implementation with CodeLlama 7B 24 | ├── v2_CoT_Llama.py # CoT implementation with Llama 3.2:3B 25 | └── v3_ReAct.py # ReAct implementation with Llama 3.2:3B 26 | ``` 27 | 28 | ## 🚀 Getting Started 29 | 30 | ### Prerequisites 31 | - Python 3.8+ 32 | - Ollama installed locally 33 | - Llama3 or compatible LLM model configured 34 | 35 | ### Installation 36 | ```bash 37 | git clone https://github.com/yourusername/CoDSPy.git 38 | cd CoDSPy 39 | pip install -r requirements.txt 40 | ``` 41 | 42 | ### Quick Start 43 | 1. Start Ollama service: 44 | ```bash 45 | ollama serve 46 | ``` 47 | 48 | 2. Run the desired implementation: 49 | ```bash 50 | # For CoT with CodeLlama:7b 51 | python v1_CoT_CodeLlama.py 52 | 53 | # For CoT with Llama 3.2:3b 54 | python v2_CoT_Llama.py 55 | 56 | # For ReAct with Llama 3.2:3b 57 | python v3_ReAct.py 58 | ``` 59 | 60 | 3. Access the interface at `http://localhost:7860` 61 | 62 | ## 🛠️ Workflow Process 63 | 1. **Code Analysis Phase**: 64 | - Syntax inspection 65 | - Performance evaluation 66 | - Best practices verification 67 | 68 | 2. **Optimization Phase**: 69 | - Code refactoring 70 | - Efficiency improvements 71 | - Readability enhancements 72 | 73 | 3. **Test Generation**: 74 | - Edge case identification 75 | - Test case creation 76 | - Unit test generation 77 | 78 | ## 📚 Documentation 79 | | Component | Technology | Description | 80 | |---------------------|------------------|--------------------------------------| 81 | | AI Framework | DSPy | CoT and ReAct reasoning | 82 | | Language Model | Ollama/Llama3 | Local LLM operations | 83 | | Web Interface | Gradio | User-friendly code editor | 84 | | Processing | CoT/ReAct | Reasoning approaches | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /codspy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devadigapratham/CoDSPy/9c570f26e145bf3dced5a842d14bc4e600feec50/codspy.png -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | dspy 2 | gradio 3 | torch 4 | transformers 5 | ollama 6 | -------------------------------------------------------------------------------- /v1_CoT_CodeLlama.py: -------------------------------------------------------------------------------- 1 | import os 2 | os.environ["CUDA_VISIBLE_DEVICES"] = "0" 3 | import dspy 4 | import gradio as gr 5 | from typing import Dict 6 | 7 | # ====================== 8 | # DSPy Modules 9 | # ====================== 10 | 11 | class CodeAnalyzer(dspy.Module): 12 | def __init__(self): 13 | super().__init__() 14 | self.analyze_code = dspy.ChainOfThought("code -> issues, suggestions") 15 | 16 | def analyze(self, code: str) -> Dict[str, str]: 17 | try: 18 | prediction = self.analyze_code(code=code) 19 | return { 20 | "issues": prediction.issues, 21 | "suggestions": prediction.suggestions 22 | } 23 | except Exception as e: 24 | return { 25 | "issues": f"Analysis error: {str(e)}", 26 | "suggestions": "No suggestions available" 27 | } 28 | 29 | class CodeOptimizer(dspy.Module): 30 | def __init__(self): 31 | super().__init__() 32 | self.optimize_code = dspy.ChainOfThought("code, suggestions -> optimized_code") 33 | 34 | def optimize(self, code: str, suggestions: str) -> str: 35 | try: 36 | prediction = self.optimize_code(code=code, suggestions=suggestions) 37 | return prediction.optimized_code 38 | except Exception as e: 39 | return f"Optimization error: {str(e)}" 40 | 41 | class TestGenerator(dspy.Module): 42 | def __init__(self): 43 | super().__init__() 44 | self.generate_tests = dspy.ChainOfThought("code -> test_cases, test_code") 45 | 46 | def create_tests(self, code: str) -> Dict[str, str]: 47 | try: 48 | prediction = self.generate_tests(code=code) 49 | return { 50 | "test_cases": prediction.test_cases, 51 | "test_code": prediction.test_code 52 | } 53 | except Exception as e: 54 | return { 55 | "test_cases": f"Test generation failed: {str(e)}", 56 | "test_code": "Unable to generate test code" 57 | } 58 | 59 | # ====================== 60 | # Core System 61 | # ====================== 62 | 63 | class CodeForge: 64 | def __init__(self): 65 | dspy.configure(lm=dspy.OllamaLocal(model='codellama:7b', device='cuda', temperature=0.2)) 66 | self.analyzer = CodeAnalyzer() 67 | self.optimizer = CodeOptimizer() 68 | self.tester = TestGenerator() 69 | 70 | def process(self, code: str) -> Dict[str, str]: 71 | analysis = self.analyzer.analyze(code) 72 | optimized = self.optimizer.optimize(code, analysis["suggestions"]) 73 | tests = self.tester.create_tests(code) 74 | 75 | return { 76 | "issues": analysis["issues"], 77 | "suggestions": analysis["suggestions"], 78 | "optimized_code": optimized, 79 | "test_cases": tests["test_cases"], 80 | "test_code": tests["test_code"] 81 | } 82 | 83 | # ====================== 84 | # Gradio Interface 85 | # ====================== 86 | 87 | def create_interface(): 88 | forge = CodeForge() 89 | 90 | with gr.Blocks(theme=gr.themes.Soft(), title="CodeForge AI") as app: 91 | gr.Markdown("# CoDSPy - AI Code Optimizer & Test Generator") 92 | 93 | with gr.Row(): 94 | with gr.Column(): 95 | input_code = gr.Code( 96 | label="Input Python Code", 97 | language="python", 98 | lines=15, 99 | elem_id="input-code" 100 | ) 101 | process_btn = gr.Button("Analyze & Improve", variant="primary") 102 | 103 | with gr.Column(): 104 | with gr.Tabs(): 105 | with gr.Tab("Analysis"): 106 | issues_out = gr.Textbox(label="Detected Issues", interactive=False, lines=3) 107 | suggestions_out = gr.Textbox(label="Optimization Suggestions", lines=5, interactive=False) 108 | 109 | with gr.Tab("Optimized Code"): 110 | optimized_code_out = gr.Code( 111 | label="Improved Code", 112 | language="python", 113 | lines=15, 114 | interactive=False 115 | ) 116 | 117 | with gr.Tab("Tests"): 118 | test_cases_out = gr.Textbox(label="Suggested Test Cases", lines=4, interactive=False) 119 | test_code_out = gr.Code( 120 | label="Generated Test Code", 121 | language="python", 122 | lines=15, 123 | interactive=False 124 | ) 125 | 126 | @process_btn.click( 127 | inputs=[input_code], 128 | outputs=[issues_out, suggestions_out, optimized_code_out, test_cases_out, test_code_out] 129 | ) 130 | def process_code(code): 131 | if not code.strip(): 132 | raise gr.Error("Please input some code to analyze!") 133 | 134 | results = forge.process(code) 135 | return ( 136 | results["issues"], 137 | results["suggestions"], 138 | results["optimized_code"], 139 | results["test_cases"], 140 | results["test_code"] 141 | ) 142 | 143 | return app 144 | 145 | if __name__ == "__main__": 146 | web_app = create_interface() 147 | web_app.launch(server_port=7860, server_name="0.0.0.0") -------------------------------------------------------------------------------- /v2_CoT_Llama.py: -------------------------------------------------------------------------------- 1 | import os 2 | os.environ["CUDA_VISIBLE_DEVICES"] = "0" 3 | import dspy 4 | import gradio as gr 5 | from typing import Dict 6 | 7 | # ====================== 8 | # DSPy Modules 9 | # ====================== 10 | 11 | class CodeAnalyzer(dspy.Module): 12 | def __init__(self): 13 | super().__init__() 14 | self.analyze_code = dspy.ChainOfThought("code -> issues, suggestions") 15 | 16 | def analyze(self, code: str) -> Dict[str, str]: 17 | try: 18 | prediction = self.analyze_code(code=code) 19 | return { 20 | "issues": prediction.issues, 21 | "suggestions": prediction.suggestions 22 | } 23 | except Exception as e: 24 | return { 25 | "issues": f"Analysis error: {str(e)}", 26 | "suggestions": "No suggestions available" 27 | } 28 | 29 | class CodeOptimizer(dspy.Module): 30 | def __init__(self): 31 | super().__init__() 32 | self.optimize_code = dspy.ChainOfThought("code, suggestions -> optimized_code") 33 | 34 | def optimize(self, code: str, suggestions: str) -> str: 35 | try: 36 | prediction = self.optimize_code(code=code, suggestions=suggestions) 37 | return prediction.optimized_code 38 | except Exception as e: 39 | return f"Optimization error: {str(e)}" 40 | 41 | class TestGenerator(dspy.Module): 42 | def __init__(self): 43 | super().__init__() 44 | self.generate_tests = dspy.ChainOfThought("code -> test_cases, test_code") 45 | 46 | def create_tests(self, code: str) -> Dict[str, str]: 47 | try: 48 | prediction = self.generate_tests(code=code) 49 | return { 50 | "test_cases": prediction.test_cases, 51 | "test_code": prediction.test_code 52 | } 53 | except Exception as e: 54 | return { 55 | "test_cases": f"Test generation failed: {str(e)}", 56 | "test_code": "Unable to generate test code" 57 | } 58 | 59 | # ====================== 60 | # Core System 61 | # ====================== 62 | 63 | class CodeForge: 64 | def __init__(self): 65 | dspy.configure(lm=dspy.OllamaLocal(model='llama3.2:3b', device='cuda', temperature=0.2)) 66 | self.analyzer = CodeAnalyzer() 67 | self.optimizer = CodeOptimizer() 68 | self.tester = TestGenerator() 69 | 70 | def process(self, code: str) -> Dict[str, str]: 71 | analysis = self.analyzer.analyze(code) 72 | optimized = self.optimizer.optimize(code, analysis["suggestions"]) 73 | tests = self.tester.create_tests(code) 74 | 75 | return { 76 | "issues": analysis["issues"], 77 | "suggestions": analysis["suggestions"], 78 | "optimized_code": optimized, 79 | "test_cases": tests["test_cases"], 80 | "test_code": tests["test_code"] 81 | } 82 | 83 | # ====================== 84 | # Gradio Interface 85 | # ====================== 86 | 87 | def create_interface(): 88 | forge = CodeForge() 89 | 90 | with gr.Blocks(theme=gr.themes.Soft(), title="CodeForge AI") as app: 91 | gr.Markdown("# CoDSPy - AI Code Optimizer & Test Generator") 92 | 93 | with gr.Row(): 94 | with gr.Column(): 95 | input_code = gr.Code( 96 | label="Input Python Code", 97 | language="python", 98 | lines=15, 99 | elem_id="input-code" 100 | ) 101 | process_btn = gr.Button("Analyze & Improve", variant="primary") 102 | 103 | with gr.Column(): 104 | with gr.Tabs(): 105 | with gr.Tab("Analysis"): 106 | issues_out = gr.Textbox(label="Detected Issues", interactive=False, lines=3) 107 | suggestions_out = gr.Textbox(label="Optimization Suggestions", lines=5, interactive=False) 108 | 109 | with gr.Tab("Optimized Code"): 110 | optimized_code_out = gr.Code( 111 | label="Improved Code", 112 | language="python", 113 | lines=15, 114 | interactive=False 115 | ) 116 | 117 | with gr.Tab("Tests"): 118 | test_cases_out = gr.Textbox(label="Suggested Test Cases", lines=4, interactive=False) 119 | test_code_out = gr.Code( 120 | label="Generated Test Code", 121 | language="python", 122 | lines=15, 123 | interactive=False 124 | ) 125 | 126 | @process_btn.click( 127 | inputs=[input_code], 128 | outputs=[issues_out, suggestions_out, optimized_code_out, test_cases_out, test_code_out] 129 | ) 130 | def process_code(code): 131 | if not code.strip(): 132 | raise gr.Error("Please input some code to analyze!") 133 | 134 | results = forge.process(code) 135 | return ( 136 | results["issues"], 137 | results["suggestions"], 138 | results["optimized_code"], 139 | results["test_cases"], 140 | results["test_code"] 141 | ) 142 | 143 | return app 144 | 145 | if __name__ == "__main__": 146 | web_app = create_interface() 147 | web_app.launch(server_port=7860, server_name="0.0.0.0") -------------------------------------------------------------------------------- /v3_ReAct.py: -------------------------------------------------------------------------------- 1 | import os 2 | os.environ["CUDA_VISIBLE_DEVICES"] = "0" 3 | import dspy 4 | import gradio as gr 5 | from typing import Dict 6 | 7 | # ====================== 8 | # DSPy Modules (Fixed ReAct Implementation) 9 | # ====================== 10 | 11 | class CodeAnalyzer(dspy.Module): 12 | def __init__(self): 13 | super().__init__() 14 | # Define tools for ReAct 15 | self.tools = [ 16 | dspy.Tool(name="code_analysis", func=self._analyze_code), 17 | dspy.Tool(name="suggestion_generator", func=self._generate_suggestions) 18 | ] 19 | self.analyze_code = dspy.ReAct("code -> issues, suggestions", tools=self.tools) 20 | 21 | def _analyze_code(self, code: str) -> str: 22 | """Tool for analyzing code issues""" 23 | return f"Analyzing code for potential issues..." 24 | 25 | def _generate_suggestions(self, issues: str) -> str: 26 | """Tool for generating suggestions""" 27 | return f"Generating optimization suggestions based on issues..." 28 | 29 | def analyze(self, code: str) -> Dict[str, str]: 30 | try: 31 | prediction = self.analyze_code(code=code) 32 | return { 33 | "issues": prediction.issues, 34 | "suggestions": prediction.suggestions 35 | } 36 | except Exception as e: 37 | return { 38 | "issues": f"Analysis error: {str(e)}", 39 | "suggestions": "No suggestions available" 40 | } 41 | 42 | class CodeOptimizer(dspy.Module): 43 | def __init__(self): 44 | super().__init__() 45 | # Define tools for ReAct 46 | self.tools = [ 47 | dspy.Tool(name="code_optimizer", func=self._optimize_code), 48 | dspy.Tool(name="code_refactor", func=self._refactor_code) 49 | ] 50 | self.optimize_code = dspy.ReAct("code, suggestions -> optimized_code", tools=self.tools) 51 | 52 | def _optimize_code(self, code: str) -> str: 53 | """Tool for code optimization""" 54 | return f"Optimizing code structure..." 55 | 56 | def _refactor_code(self, code: str) -> str: 57 | """Tool for code refactoring""" 58 | return f"Refactoring code for better readability..." 59 | 60 | def optimize(self, code: str, suggestions: str) -> str: 61 | try: 62 | prediction = self.optimize_code(code=code, suggestions=suggestions) 63 | return prediction.optimized_code 64 | except Exception as e: 65 | return f"Optimization error: {str(e)}" 66 | 67 | class TestGenerator(dspy.Module): 68 | def __init__(self): 69 | super().__init__() 70 | # Define tools for ReAct 71 | self.tools = [ 72 | dspy.Tool(name="test_case_generator", func=self._generate_test_cases), 73 | dspy.Tool(name="test_code_writer", func=self._write_test_code) 74 | ] 75 | self.generate_tests = dspy.ReAct("code -> test_cases, test_code", tools=self.tools) 76 | 77 | def _generate_test_cases(self, code: str) -> str: 78 | """Tool for generating test cases""" 79 | return f"Generating test cases..." 80 | 81 | def _write_test_code(self, test_cases: str) -> str: 82 | """Tool for writing test code""" 83 | return f"Writing test code implementation..." 84 | 85 | def create_tests(self, code: str) -> Dict[str, str]: 86 | try: 87 | prediction = self.generate_tests(code=code) 88 | return { 89 | "test_cases": prediction.test_cases, 90 | "test_code": prediction.test_code 91 | } 92 | except Exception as e: 93 | return { 94 | "test_cases": f"Test generation failed: {str(e)}", 95 | "test_code": "Unable to generate test code" 96 | } 97 | 98 | # ====================== 99 | # Core System (Unchanged) 100 | # ====================== 101 | 102 | class CodeForge: 103 | def __init__(self): 104 | dspy.configure(lm=dspy.OllamaLocal(model='llama3.2:3b', device='cuda', temperature=0.2)) 105 | self.analyzer = CodeAnalyzer() 106 | self.optimizer = CodeOptimizer() 107 | self.tester = TestGenerator() 108 | 109 | def process(self, code: str) -> Dict[str, str]: 110 | analysis = self.analyzer.analyze(code) 111 | optimized = self.optimizer.optimize(code, analysis["suggestions"]) 112 | tests = self.tester.create_tests(code) 113 | 114 | return { 115 | "issues": analysis["issues"], 116 | "suggestions": analysis["suggestions"], 117 | "optimized_code": optimized, 118 | "test_cases": tests["test_cases"], 119 | "test_code": tests["test_code"] 120 | } 121 | 122 | # ====================== 123 | # Gradio Interface 124 | # ====================== 125 | 126 | def create_interface(): 127 | forge = CodeForge() 128 | 129 | with gr.Blocks(theme=gr.themes.Soft(), title="CodeForge AI") as app: 130 | gr.Markdown("# CoDSPy - AI Code Optimizer & Test Generator") 131 | 132 | with gr.Row(): 133 | with gr.Column(): 134 | input_code = gr.Code( 135 | label="Input Python Code", 136 | language="python", 137 | lines=15, 138 | elem_id="input-code" 139 | ) 140 | process_btn = gr.Button("Analyze & Improve", variant="primary") 141 | 142 | with gr.Column(): 143 | with gr.Tabs(): 144 | with gr.Tab("Analysis"): 145 | issues_out = gr.Textbox(label="Detected Issues", interactive=False, lines=3) 146 | suggestions_out = gr.Textbox(label="Optimization Suggestions", lines=5, interactive=False) 147 | 148 | with gr.Tab("Optimized Code"): 149 | optimized_code_out = gr.Code( 150 | label="Improved Code", 151 | language="python", 152 | lines=15, 153 | interactive=False 154 | ) 155 | 156 | with gr.Tab("Tests"): 157 | test_cases_out = gr.Textbox(label="Suggested Test Cases", lines=4, interactive=False) 158 | test_code_out = gr.Code( 159 | label="Generated Test Code", 160 | language="python", 161 | lines=15, 162 | interactive=False 163 | ) 164 | 165 | @process_btn.click( 166 | inputs=[input_code], 167 | outputs=[issues_out, suggestions_out, optimized_code_out, test_cases_out, test_code_out] 168 | ) 169 | def process_code(code): 170 | if not code.strip(): 171 | raise gr.Error("Please input some code to analyze!") 172 | 173 | results = forge.process(code) 174 | return ( 175 | results["issues"], 176 | results["suggestions"], 177 | results["optimized_code"], 178 | results["test_cases"], 179 | results["test_code"] 180 | ) 181 | 182 | return app 183 | 184 | if __name__ == "__main__": 185 | web_app = create_interface() 186 | web_app.launch(server_port=7860, server_name="0.0.0.0") 187 | --------------------------------------------------------------------------------