File size: 6,662 Bytes
20718fa
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
import gradio as gr
import openai

# --- UI Configuration ---

# Extracted from the provided React code
LANGUAGES = [
    'Python', 'JavaScript', 'TypeScript', 'Java', 'C++', 'C#', 'C', 'Go', 
    'Rust', 'Swift', 'Kotlin', 'PHP', 'Ruby', 'Scala', 'R', 'MATLAB', 
    'Perl', 'Haskell', 'Lua', 'Dart', 'Elixir', 'F#', 'Clojure', 
    'Objective-C', 'Visual Basic', 'Bash', 'PowerShell', 'SQL', 'HTML', 
    'CSS', 'JSON', 'XML', 'YAML', 'Assembly', 'Fortran', 'COBOL', 
    'Pascal', 'Delphi', 'Groovy', 'Julia', 'Nim', 'Crystal', 'Zig', 
    'V', 'OCaml', 'Erlang', 'Prolog', 'Lisp', 'Scheme', 'Racket'
]

# A selection of popular and capable models available via OpenRouter
# You can expand this list with other models from openrouter.ai
MODELS = [
    "anthropic/claude-3.5-sonnet",
    "google/gemini-flash-1.5",
    "meta-llama/llama-3-8b-instruct",
    "mistralai/mistral-large",
    "openai/gpt-4o",
    "microsoft/wizardlm-2-8x22b",
]

# Default example code from the original application
DEFAULT_SOURCE_CODE = """# Example Python code
def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

print(fibonacci(10))"""

# --- Core Conversion Logic ---

def convert_code(
    source_code: str,
    source_lang: str,
    target_lang: str,
    model: str,
    api_key: str,
):
    """
    Uses an LLM via OpenRouter to convert code from one language to another.
    """
    if not source_code.strip():
        raise gr.Error("Please enter some code to convert.")
    if not api_key.strip():
        raise gr.Error("OpenRouter API key is required.")
    if not model:
        raise gr.Error("Please select a model for the conversion.")

    # Initialize the OpenAI client to point to OpenRouter's API
    client = openai.OpenAI(
        base_url="https://openrouter.ai/api/v1",
        api_key=api_key,
    )

    # Construct the prompt for the LLM
    prompt = (
        f"You are an expert programmer. Convert the following {source_lang} code "
        f"to {target_lang}. Your response should only contain the raw, converted code. "
        "Do not include any explanations, markdown formatting (like ```), or extra text."
        f"\n\n--- Start of {source_lang} Code ---\n"
        f"{source_code}\n"
        f"--- End of {source_lang} Code ---"
    )

    try:
        # Make the API call to the selected model
        completion = client.chat.completions.create(
            model=model,
            messages=[
                {"role": "user", "content": prompt},
            ],
            temperature=0.1, # Lower temperature for more deterministic output
            max_tokens=2048,
        )
        converted_code = completion.choices[0].message.content.strip()
        return converted_code

    except openai.AuthenticationError:
        raise gr.Error("Authentication failed. Please check your OpenRouter API key.")
    except Exception as e:
        # A catch-all for other potential API or network errors
        raise gr.Error(f"An error occurred during conversion: {e}")

# --- Gradio User Interface ---

with gr.Blocks(
    theme=gr.themes.Monochrome(),
    css=".gradio-container {background-color: #0f172a}" # Dark theme like the original
) as app:
    # Header
    with gr.Row():
        gr.HTML(
            """
            <div style="display: flex; align-items: center; gap: 12px; padding: 10px;">
                <svg xmlns="[http://www.w3.org/2000/svg](http://www.w3.org/2000/svg)" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="#3b82f6" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-code-xml"><path d="m18 16 4-4-4-4"/><path d="m6 8-4 4 4 4"/><path d="m14.5 4-5 16"/></svg>
                <div>
                    <h1 style="font-size: 1.5rem; font-weight: 700; color: #ffffff; margin: 0;">CodeVerter</h1>
                    <p style="font-size: 0.875rem; color: #9ca3af; margin: 0;">Programming Language Converter via OpenRouter</p>
                </div>
            </div>
            """
        )

    # API Key and Model Selection
    with gr.Accordion("⚙️ Configuration", open=True):
        openrouter_key = gr.Textbox(
            label="OpenRouter API Key",
            placeholder="Enter your OpenRouter API key here...",
            type="password",
            elem_id="api-key-textbox",
        )
        model_selection = gr.Dropdown(
            label="Select LLM Model",
            choices=MODELS,
            value=MODELS[0], # Default to the first model in the list
        )

    # Main conversion interface
    with gr.Row(equal_height=False):
        # Input column
        with gr.Column(scale=1):
            source_lang_selection = gr.Dropdown(
                label="Source Language",
                choices=LANGUAGES,
                value="Python",
            )
            source_code_input = gr.Code(
                label="Source Code",
                language="python", # Start with python syntax highlighting
                value=DEFAULT_SOURCE_CODE,
                lines=15,
            )

        # Output column
        with gr.Column(scale=1):
            target_lang_selection = gr.Dropdown(
                label="Target Language",
                choices=LANGUAGES,
                value="JavaScript",
            )
            target_code_output = gr.Code(
                label="Converted Code",
                language="javascript", # Start with javascript syntax highlighting
                lines=15,
                interactive=False, # Make it read-only
            )
    
    # Keep language highlighting in sync with dropdowns
    source_lang_selection.change(
        lambda x: gr.update(language=x.lower()),
        inputs=source_lang_selection,
        outputs=source_code_input
    )
    target_lang_selection.change(
        lambda x: gr.update(language=x.lower()),
        inputs=target_lang_selection,
        outputs=target_code_output
    )

    # Convert button and action
    convert_button = gr.Button("Convert Code", variant="primary")
    convert_button.click(
        fn=convert_code,
        inputs=[
            source_code_input,
            source_lang_selection,
            target_lang_selection,
            model_selection,
            openrouter_key,
        ],
        outputs=target_code_output,
        api_name="convert"
    )

    # Footer
    gr.HTML(
        """
        <div style="text-align: center; margin-top: 24px; color: #9ca3af; font-size: 0.875rem;">
            <p>CodeVerter uses LLMs via OpenRouter to convert code. Results may require manual review.</p>
        </div>
        """
    )

if __name__ == "__main__":
    app.launch()