CultriX commited on
Commit
991a80f
Β·
verified Β·
1 Parent(s): d3141a7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +455 -102
app.py CHANGED
@@ -1,13 +1,16 @@
1
  import gradio as gr
2
  import openai
 
 
 
3
  from gradio.themes.base import Base
4
  from gradio.themes.utils import colors, fonts, sizes
5
 
6
- # --- Custom Theme Definition ---
7
 
8
  class NordTheme(Base):
9
  """
10
- A custom Gradio theme inspired by the Nord color palette.
11
  """
12
  def __init__(self):
13
  super().__init__(
@@ -16,8 +19,13 @@ class NordTheme(Base):
16
  neutral_hue=colors.slate,
17
  font=(fonts.GoogleFont("Inter"), "ui-sans-serif", "system-ui", "sans-serif"),
18
  font_mono=(fonts.GoogleFont("Fira Code"), "ui-monospace", "monospace"),
 
 
 
19
  )
 
20
  self.set(
 
21
  body_background_fill="#2E3440",
22
  body_text_color="#ECEFF4",
23
  block_background_fill="#3B4252",
@@ -25,164 +33,509 @@ class NordTheme(Base):
25
  block_border_color="#4C566A",
26
  block_label_background_fill="#434C5E",
27
  block_label_text_color="#ECEFF4",
 
 
28
  input_background_fill="#434C5E",
29
  input_border_color="transparent",
 
 
 
30
  button_primary_background_fill="#5E81AC",
31
  button_primary_background_fill_hover="#81A1C1",
32
  button_primary_text_color="#ECEFF4",
33
  button_secondary_background_fill="#4C566A",
34
  button_secondary_background_fill_hover="#5a657a",
35
  button_secondary_text_color="#ECEFF4",
 
 
36
  border_color_accent="#5E81AC",
37
  background_fill_primary_dark="#2E3440",
38
  color_accent_soft="#4c566a",
39
  block_radius="12px",
40
- # The invalid 'button_radius' argument has been removed.
41
- # Button radius is now controlled by the properties below.
42
- radius_sm=sizes.radius_sm,
43
- radius_md=sizes.radius_md,
44
- radius_lg=sizes.radius_lg,
 
45
  )
46
 
47
- # --- UI Configuration ---
48
 
49
  PROGRAMMING_LANGUAGES = sorted([
50
  'Ada', 'Assembly', 'Bash', 'C', 'C#', 'C++', 'Clojure', 'COBOL', 'CSS',
51
- 'Crystal', 'Dart', 'Elixir', 'F#', 'Fortran', 'Go', 'GraphQL', 'Groovy',
52
- 'Haskell', 'HTML', 'Java', 'JavaScript', 'Julia', 'Kotlin', 'Lisp', 'Lua',
53
- 'Markdown', 'MATLAB', 'Nim', 'Objective-C', 'OCaml', 'Pascal', 'Perl', 'PHP',
54
- 'PowerShell', 'Prolog', 'Python', 'R', 'Ruby', 'Rust', 'Scala', 'Scheme',
55
- 'SQL', 'Svelte', 'Swift', 'TOML', 'TypeScript', 'Visual Basic', 'Vue',
56
- 'XML', 'YAML', 'Zig'
57
  ])
 
58
  LANGUAGES = ['Natural Language'] + PROGRAMMING_LANGUAGES
59
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
 
61
- MODELS = sorted([
62
- "agentica-org/deepcoder-14b-preview:free", "deepseek/deepseek-chat-v3:free",
63
- "deepseek/deepseek-r1-0528:free", "google/gemma-3-27b-it:free",
64
- "google/gemini-2.0-flash-exp:free", "meta-llama/llama-3.3-70b-instruct:free",
65
- "mistralai/devstral-small-2505:free", "mistralai/mistral-small-3.2-24b-instruct-2506:free",
66
- "moonshotai/kimi-dev-72b:free", "openrouter/cypher-alpha:free",
67
- "qwen/qwen-2.5-coder-32b-instruct:free", "qwen/qwen3-235b-a22b-04-28:free",
68
- "qwen/qwq-32b:free",
69
- ])
70
 
71
- DEFAULT_SOURCE_CODE = """# Example Python code
72
- def fibonacci(n):
73
- if n <= 1:
74
- return n
75
- return fibonacci(n-1) + fibonacci(n-2)
 
 
 
 
 
 
 
 
 
 
76
 
77
- print(fibonacci(10))"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
 
79
- # --- Core Conversion Logic ---
 
 
 
 
 
 
 
 
 
 
80
 
81
- def convert_code(
82
- source_code: str, source_lang: str, target_lang: str, model: str, api_key: str
83
- ):
84
- """
85
- Handles three conversion scenarios:
86
- 1. Natural Language -> Code
87
- 2. Code -> Natural Language
88
- 3. Code -> Code
89
- """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  if not source_code.strip():
91
- raise gr.Error("Please enter some code or a description to convert.")
 
92
  if not api_key.strip():
93
- raise gr.Error("OpenRouter API key is required.")
 
94
  if not model or not model.strip():
95
- raise gr.Error("Please select or enter a model for the conversion.")
96
-
97
  if source_lang == "Natural Language" and target_lang == "Natural Language":
98
- raise gr.Error("Please select a programming language for either the source or the target.")
99
-
100
- client = openai.OpenAI(base_url="https://openrouter.ai/api/v1", api_key=api_key)
 
 
 
101
 
 
 
 
102
  if source_lang == "Natural Language":
103
- prompt = (
104
- f"You are a programming expert. Based on the following description, write a complete and functional code snippet in {target_lang}. "
105
- f"The user's request is: '{source_code}'.\n\n"
106
- f"Your response must only contain the raw {target_lang} code without any explanations, comments, or markdown formatting (like ```)."
107
- )
 
 
 
 
 
 
 
108
  elif target_lang == "Natural Language":
109
- prompt = (
110
- f"You are a programming expert. Explain the following {source_lang} code in simple, natural English. "
111
- f"Describe what the code does, its main logic, its inputs, and what it outputs. Do not include any code in your explanation.\n\n"
112
- f"--- Start of {source_lang} Code ---\n"
113
- f"{source_code}\n"
114
- f"--- End of {source_lang} Code ---"
115
- )
 
 
 
 
 
 
 
 
116
  else:
117
- prompt = (
118
- f"You are an expert programmer. Convert the following {source_lang} code to {target_lang}. "
119
- "Your response must only contain the raw, converted code. Do not include any explanations, comments, or markdown formatting (like ```)."
120
- f"\n\n--- Start of {source_lang} Code ---\n"
121
- f"{source_code}\n"
122
- f"--- End of {source_lang} Code ---"
123
- )
 
 
 
 
 
 
124
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
125
  try:
 
126
  completion = client.chat.completions.create(
127
  model=model,
128
  messages=[{"role": "user", "content": prompt}],
129
- temperature=0.1, max_tokens=2048
 
 
130
  )
131
- return completion.choices[0].message.content.strip()
 
 
 
 
 
 
 
 
 
132
  except openai.AuthenticationError:
133
- raise gr.Error("Authentication failed. Check your OpenRouter API key.")
 
 
 
 
134
  except Exception as e:
135
- raise gr.Error(f"An error occurred: {e}")
136
 
137
- # --- Gradio User Interface ---
138
 
139
- def update_code_language(lang: str):
140
- """Updates the Code component's language and placeholder text."""
141
  if lang == "Natural Language":
142
- return gr.update(language="text", placeholder="Describe the code you want here...")
143
- return gr.update(language=lang.lower(), placeholder=f"Enter your {lang} code here...")
 
 
 
 
 
 
 
 
 
 
144
 
145
- with gr.Blocks(theme=NordTheme()) as app:
146
- gr.HTML(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
  """
148
- <div style="display: flex; align-items: center; gap: 12px; padding: 10px;">
149
- <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="#81A1C1" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m18 16 4-4-4-4"/><path d="m6 8-4 4 4 4"/><path d="m14.5 4-5 16"/></svg>
150
- <div>
151
- <h1 style="font-size: 1.5rem; font-weight: 700; color: #ECEFF4; margin: 0;">CodeVerter</h1>
152
- <p style="font-size: 0.875rem; color: #D8DEE9; margin: 0;">Code & Natural Language Converter</p>
 
 
 
 
 
 
 
 
 
 
 
153
  </div>
154
  </div>
155
  """
156
  )
157
 
158
- with gr.Accordion("βš™οΈ Configuration", open=True):
159
- openrouter_key = gr.Textbox(label="OpenRouter API Key", placeholder="Enter your OpenRouter API key...", type="password")
160
- model_selection = gr.Dropdown(label="Select or Enter a Model Name", choices=MODELS, value=MODELS[0] if MODELS else None, allow_custom_value=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
161
 
162
- with gr.Row(equal_height=False):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
163
  with gr.Column(scale=1):
164
- source_lang_selection = gr.Dropdown(label="Source Language", choices=LANGUAGES, value="Python")
165
- source_code_input = gr.Code(label="Source", language="python", value=DEFAULT_SOURCE_CODE, lines=15)
 
 
 
 
 
 
 
 
 
 
 
 
 
166
  with gr.Column(scale=1):
167
- target_lang_selection = gr.Dropdown(label="Target Language", choices=LANGUAGES, value="JavaScript")
168
- target_code_output = gr.Code(label="Result", language="javascript", lines=15, interactive=False)
169
-
170
- source_lang_selection.change(fn=update_code_language, inputs=source_lang_selection, outputs=source_code_input)
171
- target_lang_selection.change(lambda lang: gr.update(language=lang.lower() if lang != "Natural Language" else "text"), inputs=target_lang_selection, outputs=target_code_output)
172
-
173
- convert_button = gr.Button("Convert", variant="primary", scale=1)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
174
  convert_button.click(
175
  fn=convert_code,
176
- inputs=[source_code_input, source_lang_selection, target_lang_selection, model_selection, openrouter_key],
177
- outputs=target_code_output,
 
 
 
 
 
 
 
178
  api_name="convert"
179
  )
180
-
181
- gr.HTML(
182
- """<div style="text-align: center; margin-top: 24px; color: #a0aec0; font-size: 0.875rem;">
183
- <p>Powered by OpenRouter. Results may require manual review.</p>
184
- </div>"""
185
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
186
 
187
  if __name__ == "__main__":
188
- app.launch()
 
 
 
 
 
 
 
 
1
  import gradio as gr
2
  import openai
3
+ import json
4
+ import time
5
+ from typing import Optional, Tuple, Dict, Any
6
  from gradio.themes.base import Base
7
  from gradio.themes.utils import colors, fonts, sizes
8
 
9
+ # --- Enhanced Custom Theme ---
10
 
11
  class NordTheme(Base):
12
  """
13
+ Enhanced Nord theme with improved accessibility and visual polish.
14
  """
15
  def __init__(self):
16
  super().__init__(
 
19
  neutral_hue=colors.slate,
20
  font=(fonts.GoogleFont("Inter"), "ui-sans-serif", "system-ui", "sans-serif"),
21
  font_mono=(fonts.GoogleFont("Fira Code"), "ui-monospace", "monospace"),
22
+ radius_sm=sizes.radius_sm,
23
+ radius_md=sizes.radius_md,
24
+ radius_lg=sizes.radius_lg,
25
  )
26
+
27
  self.set(
28
+ # Main backgrounds
29
  body_background_fill="#2E3440",
30
  body_text_color="#ECEFF4",
31
  block_background_fill="#3B4252",
 
33
  block_border_color="#4C566A",
34
  block_label_background_fill="#434C5E",
35
  block_label_text_color="#ECEFF4",
36
+
37
+ # Input styling
38
  input_background_fill="#434C5E",
39
  input_border_color="transparent",
40
+ input_text_color="#ECEFF4",
41
+
42
+ # Button styling
43
  button_primary_background_fill="#5E81AC",
44
  button_primary_background_fill_hover="#81A1C1",
45
  button_primary_text_color="#ECEFF4",
46
  button_secondary_background_fill="#4C566A",
47
  button_secondary_background_fill_hover="#5a657a",
48
  button_secondary_text_color="#ECEFF4",
49
+
50
+ # Accent colors
51
  border_color_accent="#5E81AC",
52
  background_fill_primary_dark="#2E3440",
53
  color_accent_soft="#4c566a",
54
  block_radius="12px",
55
+
56
+ # Error and success colors
57
+ color_red="#BF616A",
58
+ color_green="#A3BE8C",
59
+ color_yellow="#EBCB8B",
60
+ color_orange="#D08770",
61
  )
62
 
63
+ # --- Enhanced Configuration ---
64
 
65
  PROGRAMMING_LANGUAGES = sorted([
66
  'Ada', 'Assembly', 'Bash', 'C', 'C#', 'C++', 'Clojure', 'COBOL', 'CSS',
67
+ 'Crystal', 'Dart', 'Elixir', 'Erlang', 'F#', 'Fortran', 'Go', 'GraphQL',
68
+ 'Groovy', 'Haskell', 'HTML', 'Java', 'JavaScript', 'Julia', 'Kotlin',
69
+ 'Lisp', 'Lua', 'Markdown', 'MATLAB', 'Nim', 'Objective-C', 'OCaml',
70
+ 'Pascal', 'Perl', 'PHP', 'PowerShell', 'Prolog', 'Python', 'R', 'Ruby',
71
+ 'Rust', 'Scala', 'Scheme', 'Shell', 'SQL', 'Svelte', 'Swift', 'TOML',
72
+ 'TypeScript', 'Visual Basic', 'Vue', 'XML', 'YAML', 'Zig'
73
  ])
74
+
75
  LANGUAGES = ['Natural Language'] + PROGRAMMING_LANGUAGES
76
 
77
+ # Enhanced model list with categorization
78
+ MODELS = {
79
+ "Code-Specialized": [
80
+ "deepseek/deepseek-coder-v2-instruct",
81
+ "mistralai/codestral-latest",
82
+ "codellama/codellama-70b-instruct",
83
+ "qwen/qwen-2.5-coder-32b-instruct:free",
84
+ "agentica-org/deepcoder-14b-preview:free",
85
+ ],
86
+ "General Purpose": [
87
+ "deepseek/deepseek-chat-v3:free",
88
+ "deepseek/deepseek-r1-0528:free",
89
+ "google/gemini-2.0-flash-exp:free",
90
+ "meta-llama/llama-3.3-70b-instruct:free",
91
+ "mistralai/mistral-small-3.2-24b-instruct-2506:free",
92
+ "qwen/qwq-32b:free",
93
+ ],
94
+ "Experimental": [
95
+ "openrouter/cypher-alpha:free",
96
+ "moonshotai/kimi-dev-72b:free",
97
+ "qwen/qwen3-235b-a22b-04-28:free",
98
+ ]
99
+ }
100
 
101
+ # Flatten models for dropdown
102
+ ALL_MODELS = []
103
+ for category, models in MODELS.items():
104
+ ALL_MODELS.extend(models)
 
 
 
 
 
105
 
106
+ DEFAULT_EXAMPLES = {
107
+ "Python": """# Example: Binary search algorithm
108
+ def binary_search(arr, target):
109
+ left, right = 0, len(arr) - 1
110
+
111
+ while left <= right:
112
+ mid = (left + right) // 2
113
+ if arr[mid] == target:
114
+ return mid
115
+ elif arr[mid] < target:
116
+ left = mid + 1
117
+ else:
118
+ right = mid - 1
119
+
120
+ return -1
121
 
122
+ # Test the function
123
+ numbers = [1, 3, 5, 7, 9, 11, 13, 15]
124
+ result = binary_search(numbers, 7)
125
+ print(f"Found at index: {result}")""",
126
+
127
+ "JavaScript": """// Example: Async data fetching with error handling
128
+ async function fetchUserData(userId) {
129
+ try {
130
+ const response = await fetch(`/api/users/${userId}`);
131
+ if (!response.ok) {
132
+ throw new Error(`HTTP error! status: ${response.status}`);
133
+ }
134
+ const userData = await response.json();
135
+ return userData;
136
+ } catch (error) {
137
+ console.error('Error fetching user data:', error);
138
+ throw error;
139
+ }
140
+ }
141
 
142
+ // Usage
143
+ fetchUserData(123)
144
+ .then(user => console.log('User:', user))
145
+ .catch(err => console.error('Failed to fetch user:', err));""",
146
+
147
+ "Natural Language": """Create a function that implements a simple calculator with the following features:
148
+ - Add, subtract, multiply, and divide two numbers
149
+ - Handle division by zero errors
150
+ - Return the result as a formatted string
151
+ - Include input validation to ensure both inputs are numbers"""
152
+ }
153
 
154
+ # --- Enhanced Conversion Logic ---
155
+
156
+ class ConversionHistory:
157
+ """Simple in-memory history management"""
158
+ def __init__(self, max_entries: int = 10):
159
+ self.history = []
160
+ self.max_entries = max_entries
161
+
162
+ def add_entry(self, source_lang: str, target_lang: str, source_code: str, result: str):
163
+ entry = {
164
+ "timestamp": time.time(),
165
+ "source_lang": source_lang,
166
+ "target_lang": target_lang,
167
+ "source_code": source_code[:200] + "..." if len(source_code) > 200 else source_code,
168
+ "result": result[:200] + "..." if len(result) > 200 else result,
169
+ }
170
+ self.history.insert(0, entry)
171
+ if len(self.history) > self.max_entries:
172
+ self.history.pop()
173
+
174
+ def get_history(self) -> str:
175
+ if not self.history:
176
+ return "No conversion history yet."
177
+
178
+ history_text = "## Recent Conversions\n\n"
179
+ for i, entry in enumerate(self.history, 1):
180
+ timestamp = time.strftime("%H:%M:%S", time.localtime(entry["timestamp"]))
181
+ history_text += f"**{i}. {timestamp}** - {entry['source_lang']} β†’ {entry['target_lang']}\n"
182
+ history_text += f"```\n{entry['source_code']}\n```\n\n"
183
+
184
+ return history_text
185
+
186
+ # Global history instance
187
+ conversion_history = ConversionHistory()
188
+
189
+ def validate_inputs(source_code: str, source_lang: str, target_lang: str, model: str, api_key: str) -> Optional[str]:
190
+ """Comprehensive input validation"""
191
  if not source_code.strip():
192
+ return "Please enter some code or a description to convert."
193
+
194
  if not api_key.strip():
195
+ return "OpenRouter API key is required."
196
+
197
  if not model or not model.strip():
198
+ return "Please select a model for the conversion."
199
+
200
  if source_lang == "Natural Language" and target_lang == "Natural Language":
201
+ return "Please select a programming language for either the source or the target."
202
+
203
+ if len(source_code) > 10000:
204
+ return "Source code is too long. Please limit to 10,000 characters."
205
+
206
+ return None
207
 
208
+ def create_conversion_prompt(source_code: str, source_lang: str, target_lang: str) -> str:
209
+ """Create optimized prompts for different conversion scenarios"""
210
+
211
  if source_lang == "Natural Language":
212
+ return f"""You are an expert programmer. Based on the following description, write complete and functional code in {target_lang}.
213
+
214
+ Requirements:
215
+ - Write clean, well-structured, and documented code
216
+ - Include proper error handling where appropriate
217
+ - Follow {target_lang} best practices and conventions
218
+ - Make the code production-ready
219
+
220
+ User's request: {source_code}
221
+
222
+ Respond with ONLY the raw {target_lang} code. Do not include explanations, markdown formatting, or code blocks."""
223
+
224
  elif target_lang == "Natural Language":
225
+ return f"""You are a programming expert. Explain the following {source_lang} code in clear, natural English.
226
+
227
+ Please provide:
228
+ 1. A brief overview of what the code does
229
+ 2. Explanation of the main logic and algorithms used
230
+ 3. Description of inputs and outputs
231
+ 4. Any notable features or techniques used
232
+
233
+ {source_lang} code to explain:
234
+ ```
235
+ {source_code}
236
+ ```
237
+
238
+ Provide a clear, educational explanation without including any code in your response."""
239
+
240
  else:
241
+ return f"""You are an expert programmer. Convert the following {source_lang} code to {target_lang}.
242
+
243
+ Requirements:
244
+ - Maintain the same functionality and logic
245
+ - Follow {target_lang} best practices and conventions
246
+ - Ensure the converted code is syntactically correct
247
+ - Keep the same variable names where possible
248
+ - Add brief comments for complex conversions
249
+
250
+ {source_lang} code to convert:
251
+ ```
252
+ {source_code}
253
+ ```
254
 
255
+ Respond with ONLY the converted {target_lang} code. Do not include explanations, markdown formatting, or code blocks."""
256
+
257
+ def convert_code(
258
+ source_code: str,
259
+ source_lang: str,
260
+ target_lang: str,
261
+ model: str,
262
+ api_key: str,
263
+ temperature: float = 0.1,
264
+ max_tokens: int = 4000
265
+ ) -> Tuple[str, str]:
266
+ """
267
+ Enhanced conversion function with better error handling and progress tracking
268
+ """
269
+
270
+ # Validate inputs
271
+ validation_error = validate_inputs(source_code, source_lang, target_lang, model, api_key)
272
+ if validation_error:
273
+ return "", f"❌ {validation_error}"
274
+
275
+ # Create client and prompt
276
+ client = openai.OpenAI(base_url="https://openrouter.ai/api/v1", api_key=api_key)
277
+ prompt = create_conversion_prompt(source_code, source_lang, target_lang)
278
+
279
  try:
280
+ # Make the API call
281
  completion = client.chat.completions.create(
282
  model=model,
283
  messages=[{"role": "user", "content": prompt}],
284
+ temperature=temperature,
285
+ max_tokens=max_tokens,
286
+ stream=False
287
  )
288
+
289
+ result = completion.choices[0].message.content.strip()
290
+
291
+ # Add to history
292
+ conversion_history.add_entry(source_lang, target_lang, source_code, result)
293
+
294
+ # Return result with success message
295
+ success_msg = f"βœ… Successfully converted from {source_lang} to {target_lang}"
296
+ return result, success_msg
297
+
298
  except openai.AuthenticationError:
299
+ return "", "❌ Authentication failed. Please check your OpenRouter API key."
300
+ except openai.RateLimitError:
301
+ return "", "❌ Rate limit exceeded. Please try again in a moment."
302
+ except openai.APIError as e:
303
+ return "", f"❌ API error: {str(e)}"
304
  except Exception as e:
305
+ return "", f"❌ Unexpected error: {str(e)}"
306
 
307
+ # --- Enhanced UI Helper Functions ---
308
 
309
+ def update_code_language(lang: str) -> Dict[str, Any]:
310
+ """Updates the Code component's language and placeholder text"""
311
  if lang == "Natural Language":
312
+ return gr.update(
313
+ language="text",
314
+ placeholder="Describe the code you want here...",
315
+ value=DEFAULT_EXAMPLES.get("Natural Language", "")
316
+ )
317
+
318
+ example_code = DEFAULT_EXAMPLES.get(lang, f"# Enter your {lang} code here...")
319
+ return gr.update(
320
+ language=lang.lower(),
321
+ placeholder=f"Enter your {lang} code here...",
322
+ value=example_code
323
+ )
324
 
325
+ def update_target_language(lang: str) -> Dict[str, Any]:
326
+ """Updates the target code display language"""
327
+ if lang == "Natural Language":
328
+ return gr.update(language="text", placeholder="Explanation will appear here...")
329
+ return gr.update(language=lang.lower(), placeholder="Converted code will appear here...")
330
+
331
+ def swap_languages(source_lang: str, target_lang: str, source_code: str, target_code: str) -> Tuple[str, str, str, str]:
332
+ """Swap source and target languages with their code"""
333
+ return target_lang, source_lang, target_code, source_code
334
+
335
+ def clear_all() -> Tuple[str, str, str]:
336
+ """Clear all input and output fields"""
337
+ return "", "", "Ready to convert!"
338
+
339
+ def get_conversion_history() -> str:
340
+ """Get formatted conversion history"""
341
+ return conversion_history.get_history()
342
+
343
+ # --- Enhanced Gradio Interface ---
344
+
345
+ def create_header():
346
+ """Create an enhanced header with better styling"""
347
+ return gr.HTML(
348
  """
349
+ <div style="background: linear-gradient(135deg, #5E81AC 0%, #81A1C1 100%);
350
+ padding: 24px; border-radius: 12px; margin-bottom: 20px;
351
+ box-shadow: 0 4px 12px rgba(0,0,0,0.3);">
352
+ <div style="display: flex; align-items: center; gap: 16px;">
353
+ <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24"
354
+ fill="none" stroke="#ECEFF4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
355
+ <path d="m18 16 4-4-4-4"/><path d="m6 8-4 4 4 4"/><path d="m14.5 4-5 16"/>
356
+ </svg>
357
+ <div>
358
+ <h1 style="font-size: 2rem; font-weight: 700; color: #ECEFF4; margin: 0;">
359
+ CodeVerter Pro
360
+ </h1>
361
+ <p style="font-size: 1rem; color: #E5E9F0; margin: 4px 0 0 0; opacity: 0.9;">
362
+ Advanced Code & Natural Language Converter
363
+ </p>
364
+ </div>
365
  </div>
366
  </div>
367
  """
368
  )
369
 
370
+ def create_footer():
371
+ """Create an enhanced footer"""
372
+ return gr.HTML(
373
+ """
374
+ <div style="text-align: center; margin-top: 32px; padding: 20px;
375
+ background: #3B4252; border-radius: 8px; border: 1px solid #4C566A;">
376
+ <p style="color: #D8DEE9; font-size: 0.9rem; margin: 0;">
377
+ πŸš€ Powered by OpenRouter β€’ Built with Gradio β€’
378
+ <a href="https://openrouter.ai/keys" target="_blank" style="color: #88C0D0;">Get API Key</a>
379
+ </p>
380
+ <p style="color: #A0AEC0; font-size: 0.8rem; margin: 8px 0 0 0;">
381
+ Always review generated code before use in production
382
+ </p>
383
+ </div>
384
+ """
385
+ )
386
+
387
+ # --- Main Application ---
388
 
389
+ with gr.Blocks(theme=NordTheme(), title="CodeVerter Pro", css="""
390
+ .gradio-container {
391
+ max-width: 1200px !important;
392
+ }
393
+ .code-container {
394
+ border-radius: 8px !important;
395
+ }
396
+ """) as app:
397
+
398
+ # Header
399
+ create_header()
400
+
401
+ # Configuration Section
402
+ with gr.Accordion("βš™οΈ Configuration", open=True):
403
+ with gr.Row():
404
+ with gr.Column(scale=2):
405
+ openrouter_key = gr.Textbox(
406
+ label="πŸ”‘ OpenRouter API Key",
407
+ placeholder="Enter your OpenRouter API key...",
408
+ type="password",
409
+ info="Get your free API key from openrouter.ai"
410
+ )
411
+ with gr.Column(scale=2):
412
+ model_selection = gr.Dropdown(
413
+ label="πŸ€– Model Selection",
414
+ choices=ALL_MODELS,
415
+ value=ALL_MODELS[0] if ALL_MODELS else None,
416
+ allow_custom_value=True,
417
+ info="Choose a model optimized for your task"
418
+ )
419
+ with gr.Column(scale=1):
420
+ temperature = gr.Slider(
421
+ minimum=0.0,
422
+ maximum=1.0,
423
+ step=0.1,
424
+ value=0.1,
425
+ label="🌑️ Temperature",
426
+ info="Controls randomness"
427
+ )
428
+
429
+ # Main Conversion Interface
430
+ with gr.Row(equal_height=True):
431
  with gr.Column(scale=1):
432
+ gr.Markdown("### πŸ“ Source")
433
+ source_lang_selection = gr.Dropdown(
434
+ label="Source Language",
435
+ choices=LANGUAGES,
436
+ value="Python",
437
+ info="Select the language of your input"
438
+ )
439
+ source_code_input = gr.Code(
440
+ label="Source Code/Description",
441
+ language="python",
442
+ value=DEFAULT_EXAMPLES["Python"],
443
+ lines=20,
444
+ show_label=False
445
+ )
446
+
447
  with gr.Column(scale=1):
448
+ gr.Markdown("### 🎯 Target")
449
+ target_lang_selection = gr.Dropdown(
450
+ label="Target Language",
451
+ choices=LANGUAGES,
452
+ value="JavaScript",
453
+ info="Select the desired output language"
454
+ )
455
+ target_code_output = gr.Code(
456
+ label="Converted Code/Explanation",
457
+ language="javascript",
458
+ lines=20,
459
+ interactive=False,
460
+ show_label=False
461
+ )
462
+
463
+ # Action Buttons
464
+ with gr.Row():
465
+ convert_button = gr.Button("πŸ”„ Convert", variant="primary", scale=2)
466
+ swap_button = gr.Button("πŸ”€ Swap Languages", variant="secondary", scale=1)
467
+ clear_button = gr.Button("πŸ—‘οΈ Clear All", variant="secondary", scale=1)
468
+
469
+ # Status and History
470
+ with gr.Row():
471
+ with gr.Column(scale=2):
472
+ status_display = gr.Textbox(
473
+ label="Status",
474
+ value="Ready to convert!",
475
+ interactive=False,
476
+ show_label=False
477
+ )
478
+ with gr.Column(scale=1):
479
+ history_button = gr.Button("πŸ“‹ View History", variant="secondary")
480
+
481
+ # History Modal
482
+ with gr.Accordion("πŸ“‹ Conversion History", open=False) as history_accordion:
483
+ history_display = gr.Markdown("No conversions yet.")
484
+
485
+ # Event Handlers
486
+ source_lang_selection.change(
487
+ fn=update_code_language,
488
+ inputs=source_lang_selection,
489
+ outputs=source_code_input
490
+ )
491
+
492
+ target_lang_selection.change(
493
+ fn=update_target_language,
494
+ inputs=target_lang_selection,
495
+ outputs=target_code_output
496
+ )
497
+
498
  convert_button.click(
499
  fn=convert_code,
500
+ inputs=[
501
+ source_code_input,
502
+ source_lang_selection,
503
+ target_lang_selection,
504
+ model_selection,
505
+ openrouter_key,
506
+ temperature
507
+ ],
508
+ outputs=[target_code_output, status_display],
509
  api_name="convert"
510
  )
511
+
512
+ swap_button.click(
513
+ fn=swap_languages,
514
+ inputs=[source_lang_selection, target_lang_selection, source_code_input, target_code_output],
515
+ outputs=[source_lang_selection, target_lang_selection, source_code_input, target_code_output]
516
  )
517
+
518
+ clear_button.click(
519
+ fn=clear_all,
520
+ outputs=[source_code_input, target_code_output, status_display]
521
+ )
522
+
523
+ history_button.click(
524
+ fn=get_conversion_history,
525
+ outputs=history_display
526
+ )
527
+
528
+ # Footer
529
+ create_footer()
530
+
531
+ # --- Launch Configuration ---
532
 
533
  if __name__ == "__main__":
534
+ app.launch(
535
+ server_name="0.0.0.0",
536
+ server_port=7860,
537
+ share=False,
538
+ debug=False,
539
+ show_error=True,
540
+ quiet=False
541
+ )