Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| from agno.agent import Agent | |
| from agno.models.google import Gemini | |
| from typing import Optional, Dict, Any | |
| import tempfile | |
| import os | |
| import ast | |
| import contextlib | |
| import io | |
| import sys | |
| from PIL import Image | |
| import subprocess | |
| import json | |
| class MultiLanguageExecutor: | |
| """A safer alternative to sandbox execution with support for multiple languages""" | |
| def __init__(self, timeout=10): | |
| self.timeout = timeout | |
| self.allowed_modules = [ | |
| 'math', 'datetime', 'collections', 'itertools', | |
| 'functools', 'heapq', 'bisect', 'array', 'string' | |
| ] | |
| # Language configurations | |
| self.language_configs = { | |
| 'python': { | |
| 'extension': '.py', | |
| 'run_command': lambda file: f'python "{file}"', | |
| 'comment_syntax': '#', | |
| 'sample_template': '''def main(): | |
| # Your code here | |
| pass | |
| if __name__ == "__main__": | |
| main()''' | |
| }, | |
| 'javascript': { | |
| 'extension': '.js', | |
| 'run_command': lambda file: f'node "{file}"', | |
| 'comment_syntax': '//', | |
| 'sample_template': '''function main() { | |
| // Your code here | |
| } | |
| main();''' | |
| }, | |
| 'typescript': { | |
| 'extension': '.ts', | |
| 'run_command': lambda file: f'npx ts-node "{file}"', | |
| 'comment_syntax': '//', | |
| 'sample_template': '''function main(): void { | |
| // Your code here | |
| } | |
| main();''' | |
| }, | |
| 'html': { | |
| 'extension': '.html', | |
| 'run_command': None, # HTML doesn't execute, just validate | |
| 'comment_syntax': '<!--', | |
| 'sample_template': '''<!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Document</title> | |
| </head> | |
| <body> | |
| <!-- Your content here --> | |
| </body> | |
| </html>''' | |
| }, | |
| 'css': { | |
| 'extension': '.css', | |
| 'run_command': None, # CSS doesn't execute, just validate | |
| 'comment_syntax': '/*', | |
| 'sample_template': '''/* Your CSS styles here */ | |
| body { | |
| font-family: Arial, sans-serif; | |
| margin: 0; | |
| padding: 0; | |
| }''' | |
| }, | |
| 'tsx': { | |
| 'extension': '.tsx', | |
| 'run_command': lambda file: f'npx ts-node "{file}"', | |
| 'comment_syntax': '//', | |
| 'sample_template': '''import React from 'react'; | |
| const Component: React.FC = () => { | |
| return ( | |
| <div> | |
| {/* Your JSX here */} | |
| </div> | |
| ); | |
| }; | |
| export default Component;''' | |
| }, | |
| 'java': { | |
| 'extension': '.java', | |
| 'run_command': lambda file: f'javac "{file}" && java "{os.path.splitext(os.path.basename(file))[0]}"', | |
| 'comment_syntax': '//', | |
| 'sample_template': '''public class Main { | |
| public static void main(String[] args) { | |
| // Your code here | |
| } | |
| }''' | |
| }, | |
| 'c': { | |
| 'extension': '.c', | |
| 'run_command': lambda file: f'gcc "{file}" -o "{os.path.splitext(file)[0]}" && "{os.path.splitext(file)[0]}"', | |
| 'comment_syntax': '//', | |
| 'sample_template': '''#include <stdio.h> | |
| int main() { | |
| // Your code here | |
| return 0; | |
| }''' | |
| }, | |
| 'cpp': { | |
| 'extension': '.cpp', | |
| 'run_command': lambda file: f'g++ "{file}" -o "{os.path.splitext(file)[0]}" && "{os.path.splitext(file)[0]}"', | |
| 'comment_syntax': '//', | |
| 'sample_template': '''#include <iostream> | |
| using namespace std; | |
| int main() { | |
| // Your code here | |
| return 0; | |
| }''' | |
| } | |
| } | |
| def run_code(self, code: str, language: str = 'python') -> Dict[str, Any]: | |
| """Execute code in the specified language with restrictions""" | |
| result = { | |
| "success": False, | |
| "output": "", | |
| "error": "", | |
| "logs": "", | |
| "language": language | |
| } | |
| if language not in self.language_configs: | |
| result["error"] = f"Unsupported language: {language}" | |
| return result | |
| config = self.language_configs[language] | |
| # For markup languages (HTML, CSS), just validate syntax | |
| if language in ['html', 'css']: | |
| return self._validate_markup(code, language) | |
| # For other languages, attempt execution | |
| return self._execute_code(code, config, result) | |
| def _validate_markup(self, code: str, language: str) -> Dict[str, Any]: | |
| """Validate HTML/CSS syntax""" | |
| result = { | |
| "success": True, | |
| "output": f"β {language.upper()} code appears to be well-formed.", | |
| "error": "", | |
| "logs": "", | |
| "language": language | |
| } | |
| # Basic validation | |
| if language == 'html': | |
| if not code.strip().startswith('<!DOCTYPE') and not code.strip().startswith('<html'): | |
| result["logs"] = "Note: Consider adding DOCTYPE and html tags for complete HTML structure." | |
| elif language == 'css': | |
| if '{' in code and '}' not in code: | |
| result["error"] = "CSS syntax error: Missing closing brace '}'" | |
| result["success"] = False | |
| return result | |
| def _execute_code(self, code: str, config: Dict, result: Dict) -> Dict[str, Any]: | |
| """Execute code for compilable/interpretable languages""" | |
| try: | |
| # Create temporary file | |
| with tempfile.NamedTemporaryFile( | |
| mode='w', | |
| suffix=config['extension'], | |
| delete=False, | |
| encoding='utf-8' | |
| ) as tmp_file: | |
| tmp_file.write(code) | |
| tmp_file_path = tmp_file.name | |
| # Special handling for Python (use the safer execution) | |
| if result["language"] == 'python': | |
| return self._run_python_safe(code) | |
| # For other languages, use subprocess with timeout | |
| if config['run_command']: | |
| cmd = config['run_command'](tmp_file_path) | |
| process = subprocess.run( | |
| cmd, | |
| shell=True, | |
| capture_output=True, | |
| text=True, | |
| timeout=self.timeout, | |
| cwd=os.path.dirname(tmp_file_path) | |
| ) | |
| result["output"] = process.stdout | |
| result["error"] = process.stderr | |
| result["success"] = process.returncode == 0 | |
| if not result["success"] and not result["error"]: | |
| result["error"] = f"Process exited with code {process.returncode}" | |
| except subprocess.TimeoutExpired: | |
| result["error"] = f"Execution timed out after {self.timeout} seconds" | |
| except FileNotFoundError as e: | |
| result["error"] = f"Required compiler/interpreter not found: {str(e)}" | |
| except Exception as e: | |
| result["error"] = f"Execution error: {str(e)}" | |
| finally: | |
| # Clean up temporary file | |
| try: | |
| if 'tmp_file_path' in locals() and os.path.exists(tmp_file_path): | |
| os.remove(tmp_file_path) | |
| # Also remove compiled files for C/C++/Java | |
| base_name = os.path.splitext(tmp_file_path)[0] | |
| for ext in ['.exe', '.class', '']: | |
| compiled_file = base_name + ext | |
| if os.path.exists(compiled_file): | |
| os.remove(compiled_file) | |
| except: | |
| pass | |
| return result | |
| def _run_python_safe(self, code: str) -> Dict[str, Any]: | |
| """Execute Python code safely with restrictions (same as original SafeCodeExecutor)""" | |
| stdout_capture = io.StringIO() | |
| stderr_capture = io.StringIO() | |
| result = { | |
| "success": False, | |
| "output": "", | |
| "error": "", | |
| "logs": "", | |
| "language": "python" | |
| } | |
| try: | |
| # Parse and validate the code | |
| parsed = ast.parse(code) | |
| # Check for disallowed constructs | |
| for node in ast.walk(parsed): | |
| if isinstance(node, (ast.Import, ast.ImportFrom)): | |
| for alias in node.names: | |
| module_name = alias.name if isinstance(node, ast.Import) else node.module | |
| if module_name and not any(module_name == allowed or module_name.startswith(allowed + '.') | |
| for allowed in self.allowed_modules): | |
| result["error"] = f"Import of module '{module_name}' is not allowed" | |
| return result | |
| # Disable dangerous functions/constructs | |
| if isinstance(node, ast.Call) and isinstance(node.func, ast.Name): | |
| if node.func.id in ['eval', 'exec', 'open', 'exit', 'quit', 'compile']: | |
| result["error"] = f"Use of '{node.func.id}' function is not allowed" | |
| return result | |
| # Execute the code with restrictions | |
| with contextlib.redirect_stdout(stdout_capture), contextlib.redirect_stderr(stderr_capture): | |
| locals_dict = {} | |
| exec(code, {"__builtins__": self._get_safe_builtins()}, locals_dict) | |
| # Check if there's a main function or similar output | |
| output = stdout_capture.getvalue() | |
| if not output and "main" in locals_dict and callable(locals_dict["main"]): | |
| output = str(locals_dict["main"]()) | |
| result["success"] = True | |
| result["output"] = output | |
| except Exception as e: | |
| result["error"] = f"Execution error: {str(e)}" | |
| result["logs"] = stderr_capture.getvalue() | |
| return result | |
| def _get_safe_builtins(self): | |
| """Create a safe subset of builtins""" | |
| safe_builtins = { | |
| 'None': None, | |
| 'True': True, | |
| 'False': False, | |
| 'bool': bool, | |
| 'int': int, | |
| 'float': float, | |
| 'str': str, | |
| 'list': list, | |
| 'tuple': tuple, | |
| 'dict': dict, | |
| 'set': set, | |
| 'len': len, | |
| 'range': range, | |
| 'sum': sum, | |
| 'min': min, | |
| 'max': max, | |
| 'abs': abs, | |
| 'round': round, | |
| 'zip': zip, | |
| 'enumerate': enumerate, | |
| 'isinstance': isinstance, | |
| 'issubclass': issubclass, | |
| 'hasattr': hasattr, | |
| 'getattr': getattr, | |
| 'setattr': setattr, | |
| } | |
| return safe_builtins | |
| class MultimodalCodingAgent: | |
| def __init__(self, gemini_api_key: str): | |
| self.gemini_api_key = gemini_api_key | |
| self.executor = MultiLanguageExecutor() | |
| # Create a single agent for all tasks | |
| self.agent = Agent( | |
| model=Gemini(id="gemini-2.0-flash", api_key=gemini_api_key), | |
| markdown=True | |
| ) | |
| # Store system prompt for use in individual requests | |
| self.system_prompt = """You are a multimodal coding assistant. Your capabilities include: | |
| 1. Analyzing images containing code or problem statements | |
| 2. Generating code solutions for coding problems in multiple programming languages | |
| 3. Explaining and debugging code execution results | |
| Follow these guidelines: | |
| - For image analysis, extract and describe any code or problem statements clearly | |
| - For code generation, write clean, efficient code with proper documentation in the requested language | |
| - For execution results, provide clear explanations of outputs or errors | |
| - Always prioritize security and avoid suggesting dangerous code constructs | |
| - Generate code in the exact format and language requested by the user | |
| - Match the user's requirements precisely without deviation""" | |
| def process_image(self, image: Image.Image, language: str = 'python') -> str: | |
| """Process an image containing code or problem statement""" | |
| prompt = f"""{self.system_prompt} | |
| Analyze this image and extract any coding problem or code snippet shown. | |
| Be very specific about what you see in the image. If you see actual code, transcribe it exactly. | |
| Describe it in clear natural language, including any: | |
| 1. Problem statement or code functionality | |
| 2. Variable assignments and function definitions | |
| 3. Logic flow and conditions | |
| 4. Expected behavior or output | |
| Format it as a proper coding problem description for {language} language. | |
| IMPORTANT: If you see actual code in the image, describe exactly what the code does, don't create a generic problem.""" | |
| # Save image to a temporary file | |
| with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as tmp: | |
| image.save(tmp.name, format="PNG") | |
| tmp_path = tmp.name | |
| try: | |
| response = self.agent.run( | |
| prompt, | |
| images=[{"filepath": tmp_path}] | |
| ) | |
| return response.content | |
| except Exception as e: | |
| error_msg = str(e) | |
| if "503" in error_msg or "Service Unavailable" in error_msg: | |
| return """β οΈ **Gemini API Temporarily Unavailable** | |
| The Gemini vision service is currently experiencing issues (503 error). This is a temporary server-side problem. | |
| **What you can do:** | |
| 1. Wait a few minutes and try again | |
| 2. Check the Gemini API status page | |
| 3. Or describe your code/problem in text instead | |
| **Based on common code patterns, I can still help you if you describe what you saw in the image in the text field below.**""" | |
| elif "API key" in error_msg: | |
| return "β **API Key Error**: Please check that your Gemini API key is valid and has access to vision features." | |
| elif "quota" in error_msg.lower() or "limit" in error_msg.lower(): | |
| return "β **Rate Limit/Quota Error**: You've exceeded the API usage limits. Please wait or upgrade your plan." | |
| else: | |
| return f"β **Error processing image**: {error_msg}\n\nπ‘ **Tip**: Try describing your code/problem in text instead." | |
| finally: | |
| # Clean up temporary file | |
| if os.path.exists(tmp_path): | |
| os.remove(tmp_path) | |
| def generate_code(self, problem_description: str, language: str = 'python') -> str: | |
| """Generate code for a given problem description in the specified language""" | |
| # Check if this is a multi-file project request | |
| multi_file_keywords = [ | |
| 'landing page', 'website', 'web app', 'mvp', 'portfolio', | |
| 'dashboard', 'form', 'html css js', 'html, css, js', | |
| 'html css javascript', 'full website', 'complete website' | |
| ] | |
| is_multi_file = any(keyword in problem_description.lower() for keyword in multi_file_keywords) | |
| if is_multi_file and language in ['html', 'css', 'javascript']: | |
| return self._generate_multi_file_project(problem_description) | |
| # Language-specific requirements and templates | |
| language_specs = { | |
| 'python': { | |
| 'requirements': """1. Write clean, efficient Python code with proper documentation | |
| 2. Include proper function definitions with type hints | |
| 3. Handle edge cases appropriately | |
| 4. Include example usage if applicable | |
| 5. Only use standard library modules (no external dependencies)""", | |
| 'format_instruction': "Format your response with the code in a ```python code block." | |
| }, | |
| 'javascript': { | |
| 'requirements': """1. Write modern JavaScript (ES6+) code with proper documentation | |
| 2. Use appropriate function declarations/expressions | |
| 3. Handle edge cases appropriately | |
| 4. Include example usage if applicable | |
| 5. Use built-in JavaScript features and methods""", | |
| 'format_instruction': "Format your response with the code in a ```javascript code block." | |
| }, | |
| 'typescript': { | |
| 'requirements': """1. Write TypeScript code with proper type annotations | |
| 2. Use interfaces and types where appropriate | |
| 3. Handle edge cases appropriately | |
| 4. Include example usage if applicable | |
| 5. Follow TypeScript best practices""", | |
| 'format_instruction': "Format your response with the code in a ```typescript code block." | |
| }, | |
| 'html': { | |
| 'requirements': """1. Write semantic HTML5 code | |
| 2. Use proper HTML structure and tags | |
| 3. Include appropriate meta tags and attributes | |
| 4. Follow accessibility best practices | |
| 5. Use semantic elements where applicable""", | |
| 'format_instruction': "Format your response with the code in a ```html code block." | |
| }, | |
| 'css': { | |
| 'requirements': """1. Write clean, organized CSS code | |
| 2. Use appropriate selectors and properties | |
| 3. Follow CSS best practices and conventions | |
| 4. Include responsive design considerations if applicable | |
| 5. Use modern CSS features where appropriate""", | |
| 'format_instruction': "Format your response with the code in a ```css code block." | |
| }, | |
| 'tsx': { | |
| 'requirements': """1. Write React TypeScript (TSX) code with proper types | |
| 2. Use React hooks and modern patterns | |
| 3. Include proper component structure | |
| 4. Follow React and TypeScript best practices | |
| 5. Handle props and state appropriately""", | |
| 'format_instruction': "Format your response with the code in a ```tsx code block." | |
| }, | |
| 'java': { | |
| 'requirements': """1. Write clean Java code following conventions | |
| 2. Use appropriate access modifiers and OOP principles | |
| 3. Handle exceptions properly | |
| 4. Include proper class and method structure | |
| 5. Follow Java naming conventions""", | |
| 'format_instruction': "Format your response with the code in a ```java code block." | |
| }, | |
| 'c': { | |
| 'requirements': """1. Write clean C code with proper structure | |
| 2. Include necessary headers | |
| 3. Handle memory management carefully | |
| 4. Use appropriate data types and functions | |
| 5. Follow C programming conventions""", | |
| 'format_instruction': "Format your response with the code in a ```c code block." | |
| }, | |
| 'cpp': { | |
| 'requirements': """1. Write modern C++ code (C++11 or later) | |
| 2. Use appropriate STL containers and algorithms | |
| 3. Follow RAII principles and best practices | |
| 4. Include proper headers and namespaces | |
| 5. Handle exceptions and edge cases appropriately""", | |
| 'format_instruction': "Format your response with the code in a ```cpp code block." | |
| } | |
| } | |
| spec = language_specs.get(language, language_specs['python']) | |
| prompt = f"""{self.system_prompt} | |
| Based on this problem description, write {language} code to solve it: | |
| {problem_description} | |
| Requirements: | |
| {spec['requirements']} | |
| {spec['format_instruction']} | |
| IMPORTANT: Generate code that exactly matches what the user requested. Do not add extra features or modify the requirements. Provide the exact output format requested.""" | |
| try: | |
| response = self.agent.run(prompt) | |
| return response.content | |
| except Exception as e: | |
| return f"Error generating code: {str(e)}" | |
| def _generate_multi_file_project(self, problem_description: str) -> str: | |
| """Generate a complete multi-file web project (HTML, CSS, JS)""" | |
| prompt = f"""{self.system_prompt} | |
| Create a complete web project based on this description: | |
| {problem_description} | |
| Generate a fully functional website with: | |
| 1. HTML file (index.html) - semantic, accessible structure | |
| 2. CSS file (styles.css) - modern, responsive styling | |
| 3. JavaScript file (script.js) - interactive functionality | |
| Requirements: | |
| - Make it responsive and mobile-friendly | |
| - Use modern web standards (HTML5, CSS3, ES6+) | |
| - Include proper meta tags and SEO basics | |
| - Add smooth animations and interactions | |
| - Follow accessibility best practices | |
| - Make it visually appealing and professional | |
| Format your response EXACTLY like this: | |
| ## π Project Files | |
| ### π index.html | |
| ```html | |
| [Complete HTML code here] | |
| ``` | |
| ### π¨ styles.css | |
| ```css | |
| [Complete CSS code here] | |
| ``` | |
| ### β‘ script.js | |
| ```javascript | |
| [Complete JavaScript code here] | |
| ``` | |
| ### π Instructions | |
| [Brief setup and usage instructions] | |
| IMPORTANT: | |
| - Generate complete, working code for each file | |
| - Make sure all files work together seamlessly | |
| - Include all necessary functionality requested | |
| - Use proper file structure and organization | |
| - Follow the exact format specified above""" | |
| try: | |
| response = self.agent.run(prompt) | |
| return response.content | |
| except Exception as e: | |
| return f"Error generating multi-file project: {str(e)}" | |
| def execute_and_explain(self, code: str, language: str = 'python') -> str: | |
| """Execute code and provide explanation of results""" | |
| # Extract code from markdown if needed | |
| code_blocks = [f'```{language}', f'```{language.lower()}', '```'] | |
| extracted_code = code | |
| for block_start in code_blocks: | |
| if block_start in code: | |
| parts = code.split(block_start) | |
| if len(parts) > 1: | |
| extracted_code = parts[1].split("```")[0].strip() | |
| break | |
| # Execute the code | |
| result = self.executor.run_code(extracted_code, language) | |
| # Generate explanation | |
| if result["success"]: | |
| prompt = f"""{self.system_prompt} | |
| The following {language} code was executed successfully: | |
| ```{language} | |
| {extracted_code} | |
| ``` | |
| Output: {result['output']} | |
| Logs: {result['logs']} | |
| Please explain what the code does and the execution results for this {language} program.""" | |
| else: | |
| prompt = f"""{self.system_prompt} | |
| The following {language} code failed to execute: | |
| ```{language} | |
| {extracted_code} | |
| ``` | |
| Error: {result['error']} | |
| Logs: {result['logs']} | |
| Please analyze the error and suggest fixes for this {language} code.""" | |
| try: | |
| response = self.agent.run(prompt) | |
| return response.content | |
| except Exception as e: | |
| return f"Error explaining execution: {str(e)}\n\nRaw execution result: {str(result)}" | |
| def save_project_files(self, content: str, project_name: str = "generated_project") -> str: | |
| """Save multi-file project to disk and return the file paths""" | |
| if "## π Project Files" not in content: | |
| return "" | |
| try: | |
| # Create project directory | |
| project_dir = os.path.join(os.getcwd(), project_name) | |
| os.makedirs(project_dir, exist_ok=True) | |
| saved_files = [] | |
| # Extract and save HTML file | |
| if "### π index.html" in content: | |
| html_start = content.find("```html") | |
| if html_start != -1: | |
| html_start = html_start + 7 | |
| html_end = content.find("```", html_start) | |
| if html_end != -1: | |
| html_content = content[html_start:html_end].strip() | |
| html_path = os.path.join(project_dir, "index.html") | |
| with open(html_path, 'w', encoding='utf-8') as f: | |
| f.write(html_content) | |
| saved_files.append("index.html") | |
| # Extract and save CSS file | |
| if "### π¨ styles.css" in content: | |
| css_start = content.find("```css") | |
| if css_start != -1: | |
| css_start = css_start + 6 | |
| css_end = content.find("```", css_start) | |
| if css_end != -1: | |
| css_content = content[css_start:css_end].strip() | |
| css_path = os.path.join(project_dir, "styles.css") | |
| with open(css_path, 'w', encoding='utf-8') as f: | |
| f.write(css_content) | |
| saved_files.append("styles.css") | |
| # Extract and save JavaScript file | |
| if "### β‘ script.js" in content: | |
| js_start = content.find("```javascript") | |
| if js_start != -1: | |
| js_start = js_start + 13 | |
| js_end = content.find("```", js_start) | |
| if js_end != -1: | |
| js_content = content[js_start:js_end].strip() | |
| js_path = os.path.join(project_dir, "script.js") | |
| with open(js_path, 'w', encoding='utf-8') as f: | |
| f.write(js_content) | |
| saved_files.append("script.js") | |
| if saved_files: | |
| return f"\n\n### πΎ Files Saved Successfully!\nπ Project saved to: `{project_dir}`\nπ Files created: {', '.join(saved_files)}\n\nπ **To view your website**: Open `index.html` in your web browser!" | |
| except Exception as e: | |
| return f"\n\nβ Error saving files: {str(e)}" | |
| return "" | |
| def create_gradio_interface(): | |
| """Create the Gradio interface for the coding agent""" | |
| agent_instance = None | |
| def process_input(api_key, language, image, text_input, save_files): | |
| nonlocal agent_instance | |
| # Initialize agent if not already done | |
| if not agent_instance: | |
| if not api_key: | |
| return "Please enter your Gemini API key first." | |
| try: | |
| agent_instance = MultimodalCodingAgent(api_key) | |
| except Exception as e: | |
| return f"Error initializing agent: {str(e)}" | |
| # Check if this is a multi-file project request | |
| multi_file_keywords = [ | |
| 'landing page', 'website', 'web app', 'mvp', 'portfolio', | |
| 'dashboard', 'form', 'html css js', 'html, css, js', | |
| 'html css javascript', 'full website', 'complete website' | |
| ] | |
| input_text = text_input if text_input else "" | |
| is_multi_file_request = any(keyword in input_text.lower() for keyword in multi_file_keywords) | |
| # Process based on input type | |
| if image is not None: | |
| # Process image | |
| problem_description = agent_instance.process_image(image, language) | |
| # Check if image processing failed | |
| if "β οΈ" in problem_description or "β" in problem_description: | |
| return problem_description | |
| # Generate code from the problem description | |
| code = agent_instance.generate_code(problem_description, language) | |
| # Handle multi-file projects | |
| if is_multi_file_request or "## π Project Files" in code: | |
| result = f"**Extracted Problem ({language.upper()}):**\n{problem_description}\n\n{code}" | |
| if save_files: | |
| save_result = agent_instance.save_project_files(code, "extracted_project") | |
| result += save_result | |
| return result | |
| # Execute and explain the code (if it's an executable language) | |
| elif language in ['python', 'javascript', 'typescript', 'tsx', 'java', 'c', 'cpp']: | |
| explanation = agent_instance.execute_and_explain(code, language) | |
| return f"**Extracted Problem ({language.upper()}):**\n{problem_description}\n\n**Generated Code:**\n{code}\n\n**Execution Results:**\n{explanation}" | |
| else: | |
| return f"**Extracted Problem ({language.upper()}):**\n{problem_description}\n\n**Generated Code:**\n{code}\n\n**Note:** {language.upper()} code cannot be executed but has been validated for syntax." | |
| elif text_input: | |
| # Generate code from text input | |
| code = agent_instance.generate_code(text_input, language) | |
| # Handle multi-file projects | |
| if is_multi_file_request or "## π Project Files" in code: | |
| result = f"{code}" | |
| if save_files: | |
| save_result = agent_instance.save_project_files(code, "generated_project") | |
| result += save_result | |
| return result | |
| # Execute and explain the code (if it's an executable language) | |
| elif language in ['python', 'javascript', 'typescript', 'tsx', 'java', 'c', 'cpp']: | |
| explanation = agent_instance.execute_and_explain(code, language) | |
| return f"**Generated Code ({language.upper()}):**\n{code}\n\n**Execution Results:**\n{explanation}" | |
| else: | |
| return f"**Generated Code ({language.upper()}):**\n{code}\n\n**Note:** {language.upper()} code cannot be executed but has been validated for syntax." | |
| else: | |
| return "Please provide either an image or text input." | |
| # Create Gradio interface | |
| with gr.Blocks(title="Multimodal Coding Agent", theme=gr.themes.Soft()) as demo: | |
| gr.Markdown("# π Multimodal Coding Agent") | |
| gr.Markdown("Upload an image of a coding problem or describe it in text, and I'll generate and execute a solution in your chosen programming language!") | |
| with gr.Row(): | |
| api_key = gr.Textbox( | |
| label="π Gemini API Key", | |
| type="password", | |
| placeholder="Enter your Gemini API key here", | |
| scale=3 | |
| ) | |
| language_dropdown = gr.Dropdown( | |
| label="π» Programming Language", | |
| choices=[ | |
| "python", "javascript", "typescript", "tsx", | |
| "java", "c", "cpp", "html", "css" | |
| ], | |
| value="python", | |
| scale=1 | |
| ) | |
| with gr.Row(): | |
| with gr.Column(): | |
| image_input = gr.Image( | |
| label="πΈ Upload Image of Coding Problem", | |
| type="pil" | |
| ) | |
| text_input = gr.Textbox( | |
| label="βοΈ Or Describe Your Coding Problem", | |
| lines=5, | |
| placeholder="Example: Write a function to reverse a string\n\nFor web projects, try:\n- Make a MVP landing page using HTML, CSS and JS\n- Create a portfolio website\n- Build a responsive dashboard" | |
| ) | |
| with gr.Row(): | |
| submit_btn = gr.Button("π― Generate & Execute Solution", variant="primary", scale=3) | |
| save_files_checkbox = gr.Checkbox( | |
| label="πΎ Save files to disk", | |
| value=False, | |
| scale=1, | |
| info="Auto-save multi-file projects" | |
| ) | |
| with gr.Column(): | |
| output = gr.Markdown(label="π Results", value="", height=600) | |
| # Language info display | |
| with gr.Row(): | |
| gr.Markdown(""" | |
| ### π Supported Languages & Features: | |
| - **Python**: Full execution with safety restrictions | |
| - **JavaScript/TypeScript**: Requires Node.js/ts-node | |
| - **Java**: Requires JDK for compilation and execution | |
| - **C/C++**: Requires GCC/G++ compiler | |
| - **HTML/CSS**: Syntax validation + Multi-file web projects | |
| - **TSX**: React TypeScript components (requires setup) | |
| ### π Multi-File Web Projects: | |
| Use keywords like "landing page", "website", "MVP", "portfolio" to generate complete web projects with HTML, CSS, and JavaScript files automatically organized and saved! | |
| ### πΈ Image Processing Tips: | |
| - **If image processing fails (503 errors)**: This is usually temporary - wait a few minutes and retry | |
| - **Alternative**: Describe your code in text instead of uploading an image | |
| - **Best images**: Clear, high-contrast code screenshots work best | |
| ### β οΈ Prerequisites: | |
| Make sure you have the required compilers/interpreters installed for code execution. | |
| """) | |
| submit_btn.click( | |
| fn=process_input, | |
| inputs=[api_key, language_dropdown, image_input, text_input, save_files_checkbox], | |
| outputs=output | |
| ) | |
| # Add examples | |
| gr.Examples( | |
| examples=[ | |
| ["python", None, "Write a function to find the factorial of a number", False], | |
| ["javascript", None, "Create a function to check if a string is a palindrome", False], | |
| ["html", None, "Make a MVP landing page using HTML, CSS and JS", True], | |
| ["html", None, "Create a responsive portfolio website", True], | |
| ["html", None, "Build a modern dashboard with navigation", True], | |
| ["java", None, "Write a class to implement a simple calculator", False], | |
| ["css", None, "Design a card component with hover effects", False], | |
| ], | |
| inputs=[language_dropdown, image_input, text_input, save_files_checkbox], | |
| ) | |
| return demo | |
| if __name__ == "__main__": | |
| demo = create_gradio_interface() | |
| demo.launch() |