prernajeet14 commited on
Commit
7186a04
Β·
verified Β·
1 Parent(s): 3b8f432

Create appp.py

Browse files
Files changed (1) hide show
  1. appp.py +803 -0
appp.py ADDED
@@ -0,0 +1,803 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import boto3
3
+ import json
4
+ import os
5
+ from typing import Optional, Tuple, List
6
+ import nbformat
7
+ from io import StringIO
8
+ import sys
9
+ import tempfile
10
+ import zipfile
11
+ from datetime import datetime
12
+ import re
13
+
14
+ class CodingCopilot:
15
+ def __init__(self):
16
+ """Initialize the coding copilot with AWS Bedrock client."""
17
+ self.setup_aws_client()
18
+
19
+ def setup_aws_client(self):
20
+ """Setup AWS Bedrock client with credentials from environment variables."""
21
+ try:
22
+ self.bedrock_client = boto3.client(
23
+ 'bedrock-runtime',
24
+ aws_access_key_id=os.getenv('AWS_ACCESS_KEY_ID'),
25
+ aws_secret_access_key=os.getenv('AWS_SECRET_ACCESS_KEY'),
26
+ region_name='us-east-1'
27
+ )
28
+ except Exception as e:
29
+ print(f"Error setting up AWS client: {e}")
30
+ self.bedrock_client = None
31
+
32
+ def call_claude(self, prompt: str, max_tokens: int = 8000) -> str:
33
+ """Call Claude 3 Haiku via AWS Bedrock with increased token limit."""
34
+ if not self.bedrock_client:
35
+ return "❌ **Error**: AWS Bedrock client not initialized. Please check your credentials."
36
+
37
+ try:
38
+ body = {
39
+ "anthropic_version": "bedrock-2023-05-31",
40
+ "max_tokens": max_tokens,
41
+ "messages": [{"role": "user", "content": prompt}],
42
+ "temperature": 0.1,
43
+ "top_p": 0.9,
44
+ }
45
+
46
+ response = self.bedrock_client.invoke_model(
47
+ modelId="anthropic.claude-3-haiku-20240307-v1:0",
48
+ contentType='application/json',
49
+ accept='application/json',
50
+ body=json.dumps(body)
51
+ )
52
+
53
+ response_body = json.loads(response['body'].read())
54
+ return response_body['content'][0]['text']
55
+
56
+ except Exception as e:
57
+ return f"❌ **Error calling Claude**: {str(e)}"
58
+
59
+ def read_python_file(self, file_path: str) -> str:
60
+ """Read content from a Python file."""
61
+ try:
62
+ with open(file_path, 'r', encoding='utf-8') as f:
63
+ return f.read()
64
+ except Exception as e:
65
+ return f"Error reading file: {str(e)}"
66
+
67
+ def read_notebook_file(self, file_path: str) -> str:
68
+ """Read and extract code from a Jupyter notebook file."""
69
+ try:
70
+ with open(file_path, 'r', encoding='utf-8') as f:
71
+ nb = nbformat.read(f, as_version=4)
72
+
73
+ code_cells = []
74
+ for cell in nb.cells:
75
+ if cell.cell_type == 'code':
76
+ code_cells.append(f"# Cell {len(code_cells) + 1}")
77
+ code_cells.append(cell.source)
78
+ code_cells.append("")
79
+
80
+ return '\n'.join(code_cells)
81
+ except Exception as e:
82
+ return f"Error reading notebook: {str(e)}"
83
+
84
+ def process_files(self, files: List) -> Tuple[str, str]:
85
+ """Process uploaded files and return combined content."""
86
+ if not files:
87
+ return "", "No files uploaded"
88
+
89
+ all_content = []
90
+ file_info = []
91
+
92
+ for file in files:
93
+ file_path = file.name
94
+ file_name = os.path.basename(file_path)
95
+ file_extension = os.path.splitext(file_path)[1].lower()
96
+
97
+ if file_extension == '.py':
98
+ content = self.read_python_file(file_path)
99
+ elif file_extension == '.ipynb':
100
+ content = self.read_notebook_file(file_path)
101
+ else:
102
+ continue
103
+
104
+ if content and not content.startswith("Error"):
105
+ all_content.append(f"# πŸ“ File: {file_name}")
106
+ all_content.append(f"# πŸ“„ Type: {file_extension}")
107
+ all_content.append("# " + "="*50)
108
+ all_content.append(content)
109
+ all_content.append("\n" + "="*60 + "\n")
110
+ file_info.append(f"{file_name}")
111
+
112
+ combined_content = '\n'.join(all_content)
113
+ status = f"βœ… Successfully loaded {len(file_info)} files: {', '.join(file_info)}"
114
+
115
+ return combined_content, status
116
+
117
+ def extract_code_blocks(self, text: str) -> List[str]:
118
+ """Extract code blocks from response text."""
119
+ code_blocks = re.findall(r'```(?:\w+)?\n(.*?)\n```', text, re.DOTALL)
120
+ return code_blocks
121
+
122
+ def create_download_file(self, content: str, filename: str = "generated_code.py") -> str:
123
+ """Create a downloadable file with the given content."""
124
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
125
+ base_name = os.path.splitext(filename)[0]
126
+ extension = os.path.splitext(filename)[1] or '.py'
127
+ filename = f"{base_name}_{timestamp}{extension}"
128
+
129
+ temp_file = tempfile.NamedTemporaryFile(mode='w', suffix=extension, delete=False)
130
+ temp_file.write(content)
131
+ temp_file.close()
132
+
133
+ return temp_file.name
134
+
135
+ def process_message(self, message: str, files: List = None, history: List = None) -> Tuple[str, Optional[str]]:
136
+ """Process user message and return response with optional download file."""
137
+ if history is None:
138
+ history = []
139
+
140
+ # Process files if provided
141
+ file_content = ""
142
+ file_status = ""
143
+ if files:
144
+ file_content, file_status = self.process_files(files)
145
+
146
+ # Detect continuation requests
147
+ continue_keywords = ['continue', 'continue the code', 'continue from where', 'keep going', 'add more', 'extend', 'complete the']
148
+ is_continuation = any(keyword in message.lower() for keyword in continue_keywords)
149
+
150
+ # Build comprehensive context from history
151
+ context = ""
152
+ if history:
153
+ if is_continuation:
154
+ context = "\n\nFull conversation context for continuation:\n"
155
+ for i, (user_msg, assistant_msg) in enumerate(history[-5:]):
156
+ context += f"Exchange {i+1}:\nUser: {user_msg}\nAssistant: {assistant_msg}\n\n"
157
+ else:
158
+ context = "\n\nRecent conversation context:\n"
159
+ for i, (user_msg, assistant_msg) in enumerate(history[-3:]):
160
+ context += f"User: {user_msg}\nAssistant: {assistant_msg}\n\n"
161
+
162
+ # Build specialized prompts based on request type
163
+ if is_continuation:
164
+ continuation_instructions = """CRITICAL INSTRUCTIONS FOR CONTINUATION:
165
+ 1. Look at the previous conversation to understand what code was generated
166
+ 2. Continue from where the previous code left off - DO NOT start from the beginning
167
+ 3. Maintain the same coding style, structure, and patterns
168
+ 4. Add new functionality or complete incomplete sections
169
+ 5. Generate substantial code (aim for 500-2000+ lines if needed)
170
+ 6. Ensure the continuation integrates seamlessly with previous code"""
171
+
172
+ file_content_section = f"\nCode files content for reference:\n```\n{file_content}\n```" if file_content else ""
173
+
174
+ final_instruction = "Based on the previous conversation, continue the code generation. Do NOT restart - pick up exactly where the previous response left off and continue building upon it. Provide substantial, complete code sections."
175
+
176
+ prompt = f"""You are an advanced coding assistant. The user is asking you to CONTINUE or EXTEND previous code.
177
+
178
+ {continuation_instructions}
179
+
180
+ User's continuation request: {message}
181
+
182
+ {file_status}
183
+
184
+ {file_content_section}
185
+
186
+ {context}
187
+
188
+ {final_instruction}"""
189
+
190
+ else:
191
+ generation_keywords = ['create', 'generate', 'build', 'make', 'develop', 'write code', 'implement', 'design']
192
+ is_generation = any(keyword in message.lower() for keyword in generation_keywords)
193
+
194
+ if is_generation:
195
+ generation_instructions = """CRITICAL INSTRUCTIONS FOR CODE GENERATION:
196
+ 1. Generate COMPLETE, COMPREHENSIVE code - aim for 500-3000+ lines when appropriate
197
+ 2. Include ALL necessary components: classes, functions, error handling, documentation
198
+ 3. Create fully functional, production-ready applications
199
+ 4. Add comprehensive comments and docstrings
200
+ 5. Include proper imports, dependencies, and structure
201
+ 6. Don't truncate or abbreviate - provide the FULL implementation
202
+ 7. If the project is large, focus on core functionality but make it complete"""
203
+
204
+ file_content_section = f"\nReference code files:\n```\n{file_content}\n```" if file_content else ""
205
+
206
+ final_instruction = "Generate comprehensive, complete code that fully implements the requested functionality. Provide extensive code with proper structure, documentation, and all necessary components."
207
+
208
+ prompt = f"""You are an advanced coding assistant specialized in generating comprehensive, production-ready code.
209
+
210
+ {generation_instructions}
211
+
212
+ User's request: {message}
213
+
214
+ {file_status}
215
+
216
+ {file_content_section}
217
+
218
+ {context}
219
+
220
+ {final_instruction}"""
221
+
222
+ else:
223
+ file_content_section = f"\nCode files content:\n```\n{file_content}\n```" if file_content else ""
224
+
225
+ prompt = f"""You are an advanced coding assistant. Provide detailed, comprehensive responses.
226
+
227
+ User's request: {message}
228
+
229
+ {file_status}
230
+
231
+ {file_content_section}
232
+
233
+ {context}
234
+
235
+ Provide a thorough and helpful response. If suggesting code changes, provide complete implementations."""
236
+
237
+ # Get response from Claude
238
+ response = self.call_claude(prompt, max_tokens=8000)
239
+
240
+ # Extract code blocks for download
241
+ code_blocks = self.extract_code_blocks(response)
242
+ download_file = None
243
+
244
+ if code_blocks:
245
+ combined_code = "\n\n".join(code_blocks)
246
+ if len(combined_code.strip()) > 50: # Only create download if substantial code
247
+ download_file = self.create_download_file(combined_code)
248
+
249
+ return response, download_file
250
+
251
+ # Initialize the copilot
252
+ copilot = CodingCopilot()
253
+
254
+ # Fixed Desktop Layout CSS with proper alignment and sizing
255
+ desktop_css = """
256
+ /* Force desktop layout */
257
+ .gradio-container {
258
+ max-width: none !important;
259
+ width: 100vw !important;
260
+ height: 100vh !important;
261
+ background: #0a0a0a !important;
262
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif !important;
263
+ color: #ffffff !important;
264
+ padding: 1rem !important;
265
+ box-sizing: border-box !important;
266
+ overflow: hidden !important;
267
+ }
268
+
269
+ /* Header Styles */
270
+ .header-container {
271
+ background: linear-gradient(135deg, #1a1a1a 0%, #2d1b1b 50%, #1a1a1a 100%) !important;
272
+ border: 1px solid #dc2626 !important;
273
+ border-radius: 16px !important;
274
+ padding: 1.5rem !important;
275
+ margin-bottom: 1rem !important;
276
+ box-shadow: 0 8px 32px rgba(220, 38, 38, 0.15) !important;
277
+ text-align: center !important;
278
+ }
279
+
280
+ .header-title {
281
+ color: #ffffff !important;
282
+ font-size: 2.2rem !important;
283
+ font-weight: 700 !important;
284
+ margin: 0 !important;
285
+ background: linear-gradient(135deg, #ffffff 0%, #dc2626 100%) !important;
286
+ -webkit-background-clip: text !important;
287
+ -webkit-text-fill-color: transparent !important;
288
+ background-clip: text !important;
289
+ }
290
+
291
+ .header-subtitle {
292
+ color: #a1a1aa !important;
293
+ font-size: 1rem !important;
294
+ margin: 0.5rem 0 0 0 !important;
295
+ font-weight: 400 !important;
296
+ }
297
+
298
+ /* DESKTOP LAYOUT - CRITICAL FIXES */
299
+ .desktop-layout {
300
+ display: flex !important;
301
+ flex-direction: row !important;
302
+ gap: 1.5rem !important;
303
+ height: calc(100vh - 200px) !important;
304
+ width: 100% !important;
305
+ align-items: stretch !important;
306
+ min-height: 700px !important;
307
+ }
308
+
309
+ /* SIDEBAR - Fixed width and proper scrolling */
310
+ .desktop-sidebar {
311
+ background: linear-gradient(180deg, #1a1a1a 0%, #0f0f0f 100%) !important;
312
+ border: 1px solid #dc2626 !important;
313
+ border-radius: 16px !important;
314
+ padding: 1.5rem !important;
315
+ width: 350px !important;
316
+ min-width: 350px !important;
317
+ max-width: 350px !important;
318
+ flex-shrink: 0 !important;
319
+ flex-grow: 0 !important;
320
+ box-shadow: 0 8px 32px rgba(220, 38, 38, 0.1) !important;
321
+ overflow-y: auto !important;
322
+ height: 100% !important;
323
+ display: flex !important;
324
+ flex-direction: column !important;
325
+ }
326
+
327
+ /* CHAT CONTAINER - Much larger and properly aligned */
328
+ .desktop-chat {
329
+ background: linear-gradient(180deg, #111111 0%, #0a0a0a 100%) !important;
330
+ border: 1px solid #262626 !important;
331
+ border-radius: 16px !important;
332
+ flex: 1 !important;
333
+ flex-grow: 1 !important;
334
+ flex-shrink: 1 !important;
335
+ display: flex !important;
336
+ flex-direction: column !important;
337
+ overflow: hidden !important;
338
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3) !important;
339
+ height: 100% !important;
340
+ min-width: 0 !important;
341
+ }
342
+
343
+ /* Override Gradio's column behavior for exact alignment */
344
+ .desktop-layout > .block:first-child {
345
+ width: 350px !important;
346
+ min-width: 350px !important;
347
+ max-width: 350px !important;
348
+ flex: none !important;
349
+ height: 100% !important;
350
+ }
351
+
352
+ .desktop-layout > .block:last-child {
353
+ flex: 1 !important;
354
+ min-width: 0 !important;
355
+ height: 100% !important;
356
+ }
357
+
358
+ /* Quick Actions Section - MOVED TO TOP */
359
+ .quick-actions-section {
360
+ order: -1 !important;
361
+ margin-bottom: 2rem !important;
362
+ padding-bottom: 1.5rem !important;
363
+ border-bottom: 1px solid #dc2626 !important;
364
+ }
365
+
366
+ .sidebar-section {
367
+ margin-bottom: 1.5rem !important;
368
+ }
369
+
370
+ .sidebar-title {
371
+ color: #dc2626 !important;
372
+ font-weight: 700 !important;
373
+ font-size: 1.1rem !important;
374
+ margin-bottom: 1rem !important;
375
+ text-transform: uppercase !important;
376
+ letter-spacing: 0.5px !important;
377
+ display: flex !important;
378
+ align-items: center !important;
379
+ gap: 0.5rem !important;
380
+ }
381
+
382
+ .capabilities-list {
383
+ color: #d1d5db !important;
384
+ font-size: 0.85rem !important;
385
+ line-height: 1.5 !important;
386
+ }
387
+
388
+ .capabilities-list strong {
389
+ color: #ffffff !important;
390
+ display: block !important;
391
+ margin-bottom: 0.3rem !important;
392
+ }
393
+
394
+ .capability-item {
395
+ margin-bottom: 1rem !important;
396
+ padding: 0.5rem 0 !important;
397
+ border-bottom: 1px solid #262626 !important;
398
+ }
399
+
400
+ .capability-item:last-child {
401
+ border-bottom: none !important;
402
+ }
403
+
404
+ /* Quick Action Buttons - Better spacing */
405
+ .quick-action-button {
406
+ background: #1a1a1a !important;
407
+ color: #dc2626 !important;
408
+ border: 1px solid #dc2626 !important;
409
+ border-radius: 8px !important;
410
+ padding: 0.8rem 1rem !important;
411
+ font-weight: 500 !important;
412
+ cursor: pointer !important;
413
+ transition: all 0.3s ease !important;
414
+ margin-bottom: 0.6rem !important;
415
+ width: 100% !important;
416
+ text-align: left !important;
417
+ font-size: 0.85rem !important;
418
+ display: flex !important;
419
+ align-items: center !important;
420
+ gap: 0.6rem !important;
421
+ }
422
+
423
+ .quick-action-button:hover {
424
+ background: #dc2626 !important;
425
+ color: #ffffff !important;
426
+ transform: translateX(3px) !important;
427
+ box-shadow: 0 4px 12px rgba(220, 38, 38, 0.2) !important;
428
+ }
429
+
430
+ /* CHAT CONTAINER - MUCH LARGER */
431
+ .chat-main {
432
+ flex: 1 !important;
433
+ display: flex !important;
434
+ flex-direction: column !important;
435
+ height: 100% !important;
436
+ overflow: hidden !important;
437
+ }
438
+
439
+ /* CHAT MESSAGES - MUCH BIGGER AREA */
440
+ .chat-messages {
441
+ flex: 1 !important;
442
+ overflow-y: auto !important;
443
+ padding: 1.5rem !important;
444
+ height: 0 !important;
445
+ min-height: 500px !important;
446
+ }
447
+
448
+ /* LARGER CHATBOT */
449
+ .chatbot {
450
+ height: 600px !important;
451
+ min-height: 600px !important;
452
+ }
453
+
454
+ .chat-input-area {
455
+ flex-shrink: 0 !important;
456
+ background: #1a1a1a !important;
457
+ border-top: 1px solid #262626 !important;
458
+ padding: 1.5rem !important;
459
+ max-height: 300px !important;
460
+ }
461
+
462
+ /* File Upload Styling */
463
+ .file-upload-area {
464
+ background: #1a1a1a !important;
465
+ border: 1px dashed #404040 !important;
466
+ border-radius: 8px !important;
467
+ padding: 1rem !important;
468
+ margin-bottom: 1rem !important;
469
+ transition: all 0.3s ease !important;
470
+ }
471
+
472
+ .file-upload-area:hover {
473
+ border-color: #dc2626 !important;
474
+ background: #262626 !important;
475
+ }
476
+
477
+ /* Input Styling - Larger */
478
+ .message-input {
479
+ background: #262626 !important;
480
+ border: 1px solid #404040 !important;
481
+ border-radius: 8px !important;
482
+ color: #ffffff !important;
483
+ padding: 1rem !important;
484
+ font-size: 0.95rem !important;
485
+ line-height: 1.4 !important;
486
+ resize: vertical !important;
487
+ transition: all 0.3s ease !important;
488
+ width: 100% !important;
489
+ margin-bottom: 1rem !important;
490
+ min-height: 80px !important;
491
+ }
492
+
493
+ .message-input:focus {
494
+ outline: none !important;
495
+ border-color: #dc2626 !important;
496
+ box-shadow: 0 0 0 2px rgba(220, 38, 38, 0.1) !important;
497
+ }
498
+
499
+ .message-input::placeholder {
500
+ color: #6b7280 !important;
501
+ }
502
+
503
+ /* Button Row */
504
+ .button-row {
505
+ display: flex !important;
506
+ gap: 1rem !important;
507
+ align-items: center !important;
508
+ justify-content: flex-end !important;
509
+ }
510
+
511
+ /* Buttons - Larger */
512
+ .primary-button {
513
+ background: linear-gradient(135deg, #dc2626 0%, #b91c1c 100%) !important;
514
+ color: white !important;
515
+ border: none !important;
516
+ border-radius: 8px !important;
517
+ padding: 0.8rem 1.5rem !important;
518
+ font-weight: 600 !important;
519
+ font-size: 0.9rem !important;
520
+ cursor: pointer !important;
521
+ transition: all 0.3s ease !important;
522
+ box-shadow: 0 4px 16px rgba(220, 38, 38, 0.2) !important;
523
+ text-transform: uppercase !important;
524
+ letter-spacing: 0.5px !important;
525
+ min-width: 80px !important;
526
+ }
527
+
528
+ .primary-button:hover {
529
+ background: linear-gradient(135deg, #b91c1c 0%, #991b1b 100%) !important;
530
+ transform: translateY(-1px) !important;
531
+ box-shadow: 0 6px 20px rgba(220, 38, 38, 0.3) !important;
532
+ }
533
+
534
+ .secondary-button {
535
+ background: #262626 !important;
536
+ color: #ffffff !important;
537
+ border: 1px solid #404040 !important;
538
+ border-radius: 8px !important;
539
+ padding: 0.8rem 1.5rem !important;
540
+ font-weight: 500 !important;
541
+ cursor: pointer !important;
542
+ transition: all 0.3s ease !important;
543
+ text-transform: uppercase !important;
544
+ letter-spacing: 0.5px !important;
545
+ font-size: 0.9rem !important;
546
+ min-width: 80px !important;
547
+ }
548
+
549
+ .secondary-button:hover {
550
+ background: #404040 !important;
551
+ border-color: #dc2626 !important;
552
+ }
553
+
554
+ /* Download Section */
555
+ .download-section {
556
+ background: #1a1a1a !important;
557
+ border: 1px solid #dc2626 !important;
558
+ border-radius: 8px !important;
559
+ padding: 1rem !important;
560
+ margin-bottom: 1rem !important;
561
+ }
562
+
563
+ /* Scrollbar - Better visibility */
564
+ ::-webkit-scrollbar {
565
+ width: 6px !important;
566
+ height: 6px !important;
567
+ }
568
+
569
+ ::-webkit-scrollbar-track {
570
+ background: #1a1a1a !important;
571
+ border-radius: 3px !important;
572
+ }
573
+
574
+ ::-webkit-scrollbar-thumb {
575
+ background: #404040 !important;
576
+ border-radius: 3px !important;
577
+ }
578
+
579
+ ::-webkit-scrollbar-thumb:hover {
580
+ background: #dc2626 !important;
581
+ }
582
+
583
+ /* Force no mobile responsiveness */
584
+ @media (min-width: 1px) {
585
+ .desktop-layout {
586
+ flex-direction: row !important;
587
+ height: calc(100vh - 200px) !important;
588
+ }
589
+
590
+ .desktop-sidebar {
591
+ width: 350px !important;
592
+ min-width: 350px !important;
593
+ max-width: 350px !important;
594
+ height: 100% !important;
595
+ }
596
+
597
+ .desktop-chat {
598
+ flex: 1 !important;
599
+ height: 100% !important;
600
+ }
601
+
602
+ .chatbot {
603
+ height: 600px !important;
604
+ min-height: 600px !important;
605
+ }
606
+ }
607
+
608
+ /* Footer */
609
+ .footer {
610
+ background: #0a0a0a !important;
611
+ border-top: 1px solid #262626 !important;
612
+ padding: 1rem !important;
613
+ text-align: center !important;
614
+ color: #6b7280 !important;
615
+ margin-top: 1rem !important;
616
+ border-radius: 8px !important;
617
+ font-size: 0.8rem !important;
618
+ }
619
+
620
+ .footer strong {
621
+ color: #dc2626 !important;
622
+ }
623
+
624
+ /* Override Gradio container behavior */
625
+ .gradio-container .block {
626
+ width: auto !important;
627
+ }
628
+
629
+ .gradio-container .contain {
630
+ padding: 0 !important;
631
+ }
632
+
633
+ /* Ensure proper text display in chat */
634
+ .message {
635
+ font-size: 0.9rem !important;
636
+ line-height: 1.6 !important;
637
+ }
638
+
639
+ /* Code blocks in chat should be readable */
640
+ pre {
641
+ background: #1a1a1a !important;
642
+ border: 1px solid #404040 !important;
643
+ border-radius: 6px !important;
644
+ padding: 1rem !important;
645
+ overflow-x: auto !important;
646
+ font-size: 0.85rem !important;
647
+ }
648
+
649
+ code {
650
+ background: #262626 !important;
651
+ padding: 2px 4px !important;
652
+ border-radius: 3px !important;
653
+ font-size: 0.85rem !important;
654
+ }
655
+ """
656
+
657
+ def process_chat_message(message, files, history):
658
+ """Process a new chat message with download support."""
659
+ if not message.strip() and not files:
660
+ return history, history, "", None, ""
661
+
662
+ if history is None:
663
+ history = []
664
+
665
+ user_msg = message
666
+ if files:
667
+ file_names = [os.path.basename(f.name) for f in files]
668
+ user_msg += f" πŸ“ *[Files: {', '.join(file_names)}]*"
669
+
670
+ # Get AI response with potential download file
671
+ ai_response, download_file = copilot.process_message(message, files, history)
672
+
673
+ # Add to history
674
+ history.append([user_msg, ai_response])
675
+
676
+ # Return download file info
677
+ download_info = ""
678
+ if download_file:
679
+ download_info = "πŸ“₯ **Code generated successfully!** Download button available below."
680
+
681
+ return history, history, "", download_file, download_info
682
+
683
+ def clear_chat():
684
+ """Clear the chat history."""
685
+ return [], [], None, ""
686
+
687
+ def quick_action(action_text):
688
+ """Handle quick action buttons."""
689
+ return action_text
690
+
691
+ # Create the main interface with FIXED desktop layout
692
+ with gr.Blocks(css=desktop_css, title="Coding Copilot Pro - Desktop", theme=gr.themes.Base()) as app:
693
+
694
+ # Header
695
+ gr.HTML("""
696
+ <div class="header-container">
697
+ <h1 class="header-title">πŸš€ CODING COPILOT PRO</h1>
698
+ <p class="header-subtitle">Advanced AI-Powered Development Assistant β€’ Powered by Claude 3 Haiku</p>
699
+ </div>
700
+ """)
701
+
702
+ # FIXED Desktop Layout - Perfect alignment
703
+ with gr.Row(elem_classes=["desktop-layout"]):
704
+
705
+ # Left Sidebar - FIXED width and PROPER ordering
706
+ with gr.Column(elem_classes=["desktop-sidebar"], scale=0, min_width=350):
707
+
708
+ # QUICK ACTIONS SECTION - MOVED TO TOP
709
+ with gr.Column(elem_classes=["quick-actions-section"]):
710
+ gr.HTML('<h3 class="sidebar-title"><span class="emoji-icon">⚑</span>QUICK ACTIONS</h3>')
711
+
712
+ quick_generate = gr.Button("πŸ”₯ Generate Code", elem_classes=["quick-action-button"])
713
+ quick_review = gr.Button("πŸ“‹ Code Review", elem_classes=["quick-action-button"])
714
+ quick_debug = gr.Button("πŸ› Debug & Fix", elem_classes=["quick-action-button"])
715
+ quick_optimize = gr.Button("⚑ Optimize Code", elem_classes=["quick-action-button"])
716
+ quick_explain = gr.Button("πŸ“– Explain Code", elem_classes=["quick-action-button"])
717
+ quick_test = gr.Button("πŸ§ͺ Create Tests", elem_classes=["quick-action-button"])
718
+
719
+ # Capabilities Section - Below quick actions
720
+ with gr.Column(elem_classes=["sidebar-section"]):
721
+ gr.HTML('<h3 class="sidebar-title"><span class="emoji-icon">🎯</span>CAPABILITIES</h3>')
722
+
723
+ gr.HTML("""
724
+ <div class="capabilities-list">
725
+ <div class="capability-item">
726
+ <strong>πŸ’» Code Generation</strong>
727
+ Complete applications, modules, algorithms & APIs
728
+ </div>
729
+ <div class="capability-item">
730
+ <strong>πŸ” Code Analysis</strong>
731
+ Reviews, optimization, security & architecture
732
+ </div>
733
+ <div class="capability-item">
734
+ <strong>πŸ› Debug & Test</strong>
735
+ Error fixes, unit tests & refactoring
736
+ </div>
737
+ <div class="capability-item">
738
+ <strong>πŸ“š Documentation</strong>
739
+ Docstrings, API docs & explanations
740
+ </div>
741
+ </div>
742
+ """)
743
+
744
+ # Right Chat Container - MUCH LARGER and properly aligned
745
+ with gr.Column(elem_classes=["desktop-chat"], scale=1):
746
+
747
+ with gr.Column(elem_classes=["chat-main"]):
748
+ # MUCH LARGER Chat messages area
749
+ chatbot = gr.Chatbot(
750
+ height=600,
751
+ show_label=False,
752
+ container=False,
753
+ bubble_full_width=False,
754
+ avatar_images=("πŸ‘¨β€πŸ’»", "πŸ€–"),
755
+ elem_classes=["chat-messages", "chatbot"]
756
+ )
757
+
758
+ # Input area at bottom - better organized
759
+ with gr.Column(elem_classes=["chat-input-area"]):
760
+ # Download status and file
761
+ download_status = gr.HTML("", visible=True)
762
+ download_file = gr.File(label="πŸ“₯ Download Generated Code", visible=False)
763
+
764
+ # File upload - better positioned
765
+ files = gr.File(
766
+ label="πŸ“Ž Upload Code Files (.py, .ipynb)",
767
+ file_count="multiple",
768
+ file_types=[".py", ".ipynb"],
769
+ container=True,
770
+ elem_classes=["file-upload-area"]
771
+ )
772
+
773
+ # LARGER Message input
774
+ msg = gr.Textbox(
775
+ label="",
776
+ placeholder="Describe what you want to build, analyze, or improve... Type 'continue' to extend previous code.",
777
+ show_label=False,
778
+ lines=3,
779
+ max_lines=6,
780
+ elem_classes=["message-input"]
781
+ )
782
+
783
+ # Button row - better spaced
784
+ with gr.Row(elem_classes=["button-row"]):
785
+ clear = gr.Button("CLEAR", variant="secondary", elem_classes=["secondary-button"])
786
+ submit = gr.Button("SEND", variant="primary", elem_classes=["primary-button"])
787
+
788
+ # Hidden state
789
+ chat_history = gr.State([])
790
+
791
+ # Event handlers
792
+ def handle_submit(message, files, history):
793
+ result = process_chat_message(message, files, history)
794
+ return result
795
+
796
+ # Quick actions with better prompts
797
+ quick_generate.click(
798
+ lambda: "Please generate a complete, production-ready application based on the requirements. Include all necessary components, error handling, documentation, and best practices. Provide comprehensive code with full functionality.",
799
+ outputs=msg
800
+ )
801
+
802
+ quick_review.click(
803
+ lambda: "Please perform a comprehensive code review of the uploaded files. Analyze code quality, identify potential bugs, suggest performance improvements,