import gradio as gr import requests import os from typing import Dict, Tuple # Constants DEFAULTS = { "SYSTEM_MESSAGE": "You are CodePal.ai, an expert AI assistant specialized in helping programmers. You generate clean, efficient, and well-documented code based on user requirements.", "MAX_TOKENS": 4000, "TEMPERATURE": 0.7, "TOP_P": 0.95, } API_URLS = { "CODE_GENERATOR": "https://api.codepal.ai/v1/code-generator/query", "CODE_FIXER": "https://api.codepal.ai/v1/code-fixer/query", "CODE_EXTENDER": "https://api.codepal.ai/v1/code-extender/query", } def get_api_key() -> str: """Fetch API key from environment variables.""" return os.environ.get("CODEPAL_API_KEY", "") def is_api_key_valid() -> bool: """Validate if the API key is set and not a placeholder.""" api_key = get_api_key() return bool(api_key) and api_key != "YOUR_API_KEY" def build_request_data(language: str, instructions: str, flavor: str, max_tokens: int, temperature: float, top_p: float) -> Dict: """Construct the request data for API calls.""" return { "language": language, "instructions": instructions, "flavor": flavor, "max_tokens": max_tokens, "temperature": temperature, "top_p": top_p } def handle_api_response(response) -> Tuple[bool, str]: """Handle API response and return success status and result.""" if response.status_code != 200: error_message = "API request failed" try: error_data = response.json() error_message = error_data.get("error", error_message) except Exception: error_message = f"API request failed with status code {response.status_code}" return False, f"Error: {error_message}" result = response.json() if "error" in result: return False, f"Error: {result['error']}" return True, result["result"] def generate_code(language: str, requirements: str, code_style: str, include_tests: bool, max_tokens: int = DEFAULTS["MAX_TOKENS"], temperature: float = DEFAULTS["TEMPERATURE"], top_p: float = DEFAULTS["TOP_P"]) -> Tuple[bool, str]: """Generate code using CodePal.ai API.""" if not is_api_key_valid(): return False, "Error: CodePal.ai API key is not configured. Please set the CODEPAL_API_KEY environment variable." flavor = { "minimal": "minimal", "verbose": "documented" }.get(code_style, "standard") if code_style in ["minimal", "verbose"] else "tests" if include_tests else "standard" api_key = get_api_key() headers = { "Authorization": f"Bearer {api_key}", "Content-Type": "application/json" } data = build_request_data(language, requirements, flavor, max_tokens, temperature, top_p) try: response = requests.post(API_URLS["CODE_GENERATOR"], headers=headers, json=data) return handle_api_response(response) except Exception as e: return False, f"Error: {str(e)}" def fix_code(code: str, instructions: str, language: str = "", max_tokens: int = DEFAULTS["MAX_TOKENS"], temperature: float = DEFAULTS["TEMPERATURE"], top_p: float = DEFAULTS["TOP_P"]) -> Tuple[bool, str]: """Fix existing code using CodePal.ai API.""" if not is_api_key_valid(): return False, "Error: CodePal.ai API key is not configured. Please set the CODEPAL_API_KEY environment variable." api_key = get_api_key() headers = { "Authorization": f"Bearer {api_key}", "Content-Type": "application/json" } data = build_request_data(language, instructions, "", max_tokens, temperature, top_p) if language and language != "auto-detect": data["language"] = language try: response = requests.post(API_URLS["CODE_FIXER"], headers=headers, json=data) return handle_api_response(response) except Exception as e: return False, f"Error: {str(e)}" def extend_code(code: str, instructions: str, language: str = "", max_tokens: int = DEFAULTS["MAX_TOKENS"], temperature: float = DEFAULTS["TEMPERATURE"], top_p: float = DEFAULTS["TOP_P"]) -> Tuple[bool, str]: """Extend existing code using CodePal.ai API.""" if not is_api_key_valid(): return False, "Error: CodePal.ai API key is not configured. Please set the CODEPAL_API_KEY environment variable." api_key = get_api_key() headers = { "Authorization": f"Bearer {api_key}", "Content-Type": "application/json" } data = build_request_data(language, instructions, "", max_tokens, temperature, top_p) if language and language != "auto-detect": data["language"] = language try: response = requests.post(API_URLS["CODE_EXTENDER"], headers=headers, json=data) return handle_api_response(response) except Exception as e: return False, f"Error: {str(e)}" def save_to_file(code: str, language: str, file_name: str = "generated_code") -> str: """Save the generated code to a file with appropriate extension.""" extensions = { "python": ".py", "javascript": ".js", "typescript": ".ts", "java": ".java", "c": ".c", "cpp": ".cpp", "csharp": ".cs", "go": ".go", "rust": ".rs", "php": ".php", "ruby": ".rb", "swift": ".swift", "kotlin": ".kt", "html": ".html", "css": ".css", "sql": ".sql", "shell": ".sh", } extension = extensions.get(language.lower(), ".txt") full_file_name = f"{file_name}{extension}" try: with open(full_file_name, "w") as f: f.write(code) return f"Code successfully saved to {full_file_name}" except Exception as e: return f"Error saving code to file: {str(e)}" def ui_generate_code(language: str, generation_type: str, requirements: str, code_style: str, dependencies: str, include_tests: bool, max_tokens: int = DEFAULTS["MAX_TOKENS"], temperature: float = DEFAULTS["TEMPERATURE"], top_p: float = DEFAULTS["TOP_P"], save_file: bool = False) -> str: """UI handler for code generation.""" combined_requirements = f"{generation_type}: {requirements}" if dependencies: combined_requirements += f"\nDependencies: {dependencies}" success, result = generate_code(language, combined_requirements, code_style, include_tests, max_tokens, temperature, top_p) if not success: return result if save_file: file_message = save_to_file(result, language) result = f"{result}\n\n{file_message}" return result def ui_fix_code(code: str, instructions: str, language: str, max_tokens: int = DEFAULTS["MAX_TOKENS"], temperature: float = DEFAULTS["TEMPERATURE"], top_p: float = DEFAULTS["TOP_P"], save_file: bool = False) -> str: """UI handler for code fixing.""" success, result = fix_code(code, instructions, language, max_tokens, temperature, top_p) if not success: return result if save_file: file_message = save_to_file(result, language, "fixed_code") result = f"{result}\n\n{file_message}" return result def ui_extend_code(code: str, instructions: str, language: str, max_tokens: int = DEFAULTS["MAX_TOKENS"], temperature: float = DEFAULTS["TEMPERATURE"], top_p: float = DEFAULTS["TOP_P"], save_file: bool = False) -> str: """UI handler for code extension.""" success, result = extend_code(code, instructions, language, max_tokens, temperature, top_p) if not success: return result if save_file: file_message = save_to_file(result, language, "extended_code") result = f"{result}\n\n{file_message}" return result # Create Gradio Interface with tabs for different functionality with gr.Blocks(title="CodePal.ai Interface") as app: gr.Markdown( """ # CodePal.ai Code Generator A custom interface for the CodePal.ai API providing code generation, fixing, and extension capabilities. **Note**: You need to set the `CODEPAL_API_KEY` environment variable with your CodePal.ai API key. """ ) api_key_status = gr.Markdown( "⚠️ **API Key Status**: Checking..." if is_api_key_valid() else "❌ **API Key Status**: Missing. Please set the CODEPAL_API_KEY environment variable." ) with gr.Tabs(): # Generate Code Tab with gr.TabItem("Generate Code"): with gr.Row(): with gr.Column(scale=1): language = gr.Dropdown( choices=["javascript", "typescript", "python", "react", "vue", "node", "php", "java", "csharp", "html", "css", "ruby", "go", "rust", "swift"], value="javascript", label="Language/Framework" ) generation_type = gr.Radio( choices=["component", "function", "api", "algorithm", "style", "other"], value="function", label="Generation Type" ) requirements = gr.Textbox( lines=5, placeholder="Describe what you need in detail. Example: Create a function that sorts an array of objects by a specific property.", label="Requirements", info="Be as specific as possible for better results." ) with gr.Accordion("Advanced Options", open=False): code_style = gr.Dropdown( choices=["standard", "functional", "oop", "minimal", "verbose"], value="standard", label="Code Style" ) dependencies = gr.Textbox( lines=2, placeholder="E.g., react-router-dom, lodash, axios", label="Dependencies (optional)", info="List any packages or libraries you want to use." ) include_tests = gr.Checkbox( label="Include unit tests", value=False ) with gr.Group(): gr.Markdown("### Model Settings") max_tokens = gr.Slider( minimum=1000, maximum=8000, step=100, value=DEFAULTS["MAX_TOKENS"], label="Max Tokens", info="Maximum number of tokens (words) in the generated response" ) temperature = gr.Slider( minimum=0.1, maximum=1.0, step=0.05, value=DEFAULTS["TEMPERATURE"], label="Temperature", info="Higher values make output more random, lower values make it more deterministic" ) top_p = gr.Slider( minimum=0.5, maximum=1.0, step=0.05, value=DEFAULTS["TOP_P"], label="Top P", info="Controls diversity via nucleus sampling" ) save_gen_file = gr.Checkbox( label="Save generated code to file", value=False, info="Automatically save the generated code to a file with appropriate extension" ) generate_btn = gr.Button("Generate Code", variant="primary") with gr.Column(scale=1): output_code = gr.Code( label="Generated Code", language="javascript", interactive=False, lines=20 ) generate_btn.click( fn=ui_generate_code, inputs=[language, generation_type, requirements, code_style, dependencies, include_tests, max_tokens, temperature, top_p], outputs=[output_code] ) language.change( fn=lambda lang: gr.update(language=lang.lower()), inputs=[language], outputs=[output_code] ) # Fix Code Tab with gr.TabItem("Fix Code"): with gr.Row(): with gr.Column(scale=1): fix_language = gr.Dropdown( choices=["auto-detect", "javascript", "typescript", "python", "react", "vue", "node", "php", "java", "csharp", "html", "css", "ruby", "go", "rust", "swift"], value="auto-detect", label="Language (optional)" ) original_code = gr.Code( label="Code to Fix", language="javascript", lines=10 ) fix_instructions = gr.Textbox( lines=3, placeholder="Describe what's wrong or what needs to be fixed.", label="Fix Instructions", info="Be specific about the issues or errors you want resolved." ) with gr.Accordion("Advanced Model Settings", open=False): fix_max_tokens = gr.Slider( minimum=1000, maximum=8000, step=100, value=DEFAULTS["MAX_TOKENS"], label="Max Tokens", info="Maximum number of tokens (words) in the generated response" ) fix_temperature = gr.Slider( minimum=0.1, maximum=1.0, step=0.05, value=DEFAULTS["TEMPERATURE"], label="Temperature", info="Higher values make output more random, lower values make it more deterministic" ) fix_top_p = gr.Slider( minimum=0.5, maximum=1.0, step=0.05, value=DEFAULTS["TOP_P"], label="Top P", info="Controls diversity via nucleus sampling" ) save_fix_file = gr.Checkbox( label="Save fixed code to file", value=False, info="Automatically save the fixed code to a file with appropriate extension" ) fix_btn = gr.Button("Fix Code", variant="primary") with gr.Column(scale=1): fixed_code = gr.Code( label="Fixed Code", language="javascript", interactive=False, lines=20 ) fix_btn.click( fn=ui_fix_code, inputs=[original_code, fix_instructions, fix_language, fix_max_tokens, fix_temperature, fix_top_p], outputs=[fixed_code] ) fix_language.change( fn=lambda lang: gr.update(language=lang.lower() if lang != "auto-detect" else "javascript"), inputs=[fix_language], outputs=[fixed_code] ) # Extend Code Tab with gr.TabItem("Extend Code"): with gr.Row(): with gr.Column(scale=1): extend_language = gr.Dropdown( choices=["auto-detect", "javascript", "typescript", "python", "react", "vue", "node", "php", "java", "csharp", "html", "css", "ruby", "go", "rust", "swift"], value="auto-detect", label="Language (optional)" ) base_code = gr.Code( label="Base Code", language="javascript", lines=10 ) extend_instructions = gr.Textbox( lines=3, placeholder="Describe how you want to extend the code.", label="Extension Instructions", info="Be specific about what new functionality or features you want to add." ) with gr.Accordion("Advanced Model Settings", open=False): extend_max_tokens = gr.Slider( minimum=1000, maximum=8000, step=100, value=DEFAULTS["MAX_TOKENS"], label="Max Tokens", info="Maximum number of tokens (words) in the generated response" ) extend_temperature = gr.Slider( minimum=0.1, maximum=1.0, step=0.05, value=DEFAULTS["TEMPERATURE"], label="Temperature", info="Higher values make output more random, lower values make it more deterministic" ) extend_top_p = gr.Slider( minimum=0.5, maximum=1.0, step=0.05, value=DEFAULTS["TOP_P"], label="Top P", info="Controls diversity via nucleus sampling" ) extend_btn = gr.Button("Extend Code", variant="primary") with gr.Column(scale=1): extended_code = gr.Code( label="Extended Code", language="javascript", interactive=False, lines=20 ) extend_btn.click( fn=ui_extend_code, inputs=[base_code, extend_instructions, extend_language, extend_max_tokens, extend_temperature, extend_top_p], outputs=[extended_code] ) extend_language.change( fn=lambda lang: gr.update(language=lang.lower() if lang != "auto-detect" else "javascript"), inputs=[extend_language], outputs=[extended_code] ) # Launch the app if __name__ == "__main__": import sys port = int(os.environ.get("GRADIO_SERVER_PORT", 5000)) alt_port = 6000 try: app.launch( server_name="0.0.0.0", server_port=port, share=True, debug=True ) except OSError: print(f"Port {port} is in use, trying port {alt_port} instead...") app.launch( server_name="0.0.0.0", server_port=alt_port, share=True, debug=True ) except Exception as e: print(f"Error starting the Gradio application: {str(e)}") sys.exit(1)