prernajeet14 commited on
Commit
3bcb01b
Β·
verified Β·
1 Parent(s): 686307f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +510 -560
app.py CHANGED
@@ -14,7 +14,6 @@ class CodingCopilot:
14
  def __init__(self):
15
  """Initialize the coding copilot with AWS Bedrock client."""
16
  self.setup_aws_client()
17
- self.chat_history = []
18
 
19
  def setup_aws_client(self):
20
  """Setup AWS Bedrock client with credentials from environment variables."""
@@ -23,7 +22,7 @@ class CodingCopilot:
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' # Claude is available in us-east-1
27
  )
28
  except Exception as e:
29
  print(f"Error setting up AWS client: {e}")
@@ -32,19 +31,13 @@ class CodingCopilot:
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
- # Prepare the request payload for Claude
39
  body = {
40
  "anthropic_version": "bedrock-2023-05-31",
41
  "max_tokens": max_tokens,
42
- "messages": [
43
- {
44
- "role": "user",
45
- "content": prompt
46
- }
47
- ],
48
  "temperature": 0.1,
49
  "top_p": 0.9,
50
  }
@@ -60,7 +53,7 @@ class CodingCopilot:
60
  return response_body['content'][0]['text']
61
 
62
  except Exception as e:
63
- return f"Error calling Claude: {str(e)}"
64
 
65
  def read_python_file(self, file_path: str) -> str:
66
  """Read content from a Python file."""
@@ -81,14 +74,14 @@ class CodingCopilot:
81
  if cell.cell_type == 'code':
82
  code_cells.append(f"# Cell {len(code_cells) + 1}")
83
  code_cells.append(cell.source)
84
- code_cells.append("") # Add empty line between cells
85
 
86
  return '\n'.join(code_cells)
87
  except Exception as e:
88
  return f"Error reading notebook: {str(e)}"
89
 
90
- def process_multiple_files(self, files: List) -> Tuple[str, str]:
91
- """Process multiple uploaded files and return combined content."""
92
  if not files:
93
  return "", "No files uploaded"
94
 
@@ -108,215 +101,117 @@ class CodingCopilot:
108
  continue
109
 
110
  if content and not content.startswith("Error"):
111
- all_content.append(f"# File: {file_name}")
112
- all_content.append(f"# Type: {file_extension}")
113
  all_content.append("# " + "="*50)
114
  all_content.append(content)
115
  all_content.append("\n" + "="*60 + "\n")
116
- file_info.append(f"{file_name} ({file_extension})")
117
 
118
  combined_content = '\n'.join(all_content)
119
- status = f"Successfully loaded {len(file_info)} files: {', '.join(file_info)}"
120
 
121
  return combined_content, status
122
 
123
- def analyze_code_with_chat(self, code_content: str, analysis_type: str, custom_prompt: str = "", chat_history: List = None) -> Tuple[str, List]:
124
- """Analyze code with chat functionality and support for long responses."""
125
- if chat_history is None:
126
- chat_history = []
127
 
128
- # If this is the first analysis, do the standard analysis
129
- if not chat_history:
130
- result = self.analyze_code(code_content, analysis_type, custom_prompt)
131
- chat_history.append(("Initial Analysis", result))
132
- return result, chat_history
133
- else:
134
- # This is a follow-up question
135
- context = ""
136
- if chat_history:
137
- context = "\n\nPrevious analysis conversation:\n"
138
- for i, (q, a) in enumerate(chat_history[-3:]): # Last 3 exchanges for context
139
- context += f"Q{i+1}: {q}\nA{i+1}: {a}\n"
140
-
141
- prompt = f"""Given this code:
142
-
143
- ```python
144
- {code_content}
145
- ```
146
- {context}
147
-
148
- Follow-up question about the analysis: {custom_prompt}
149
-
150
- Please provide a detailed response based on the code and previous analysis. If you're providing code, make sure to include the complete implementation without truncation."""
151
-
152
- response = self.call_claude(prompt, max_tokens=8000)
153
- chat_history.append((custom_prompt, response))
154
- return response, chat_history
155
-
156
- def analyze_code(self, code_content: str, analysis_type: str, custom_prompt: str = "") -> str:
157
- """Analyze code using Claude with optional custom prompt."""
158
- base_prompts = {
159
- "review": f"""Please review this code and provide:
160
- 1. Code quality assessment
161
- 2. Potential bugs or issues
162
- 3. Performance improvements
163
- 4. Best practices suggestions
164
- 5. Security considerations
165
-
166
- Make sure to provide complete analysis with detailed explanations.""",
167
-
168
- "explain": f"""Please explain this code in detail:
169
- 1. What does this code do?
170
- 2. How does it work?
171
- 3. Key functions and their purposes
172
- 4. Dependencies and requirements
173
- 5. Usage examples
174
-
175
- Provide comprehensive explanations for each part.""",
176
-
177
- "optimize": f"""Please optimize this code:
178
- 1. Suggest performance improvements
179
- 2. Refactor for better readability
180
- 3. Reduce complexity where possible
181
- 4. Improve memory usage
182
- 5. Provide the complete optimized version
183
-
184
- Make sure to include the full optimized code without truncation.""",
185
-
186
- "debug": f"""Please help debug this code:
187
- 1. Identify potential bugs
188
- 2. Suggest fixes
189
- 3. Add error handling
190
- 4. Improve robustness
191
- 5. Provide the complete corrected version
192
-
193
- Include the full corrected code implementation.""",
194
-
195
- "document": f"""Please add comprehensive documentation to this code:
196
- 1. Add docstrings to functions/classes
197
- 2. Add inline comments
198
- 3. Create usage examples
199
- 4. Document parameters and return values
200
- 5. Add type hints where appropriate
201
-
202
- Provide the complete documented version of the code.""",
203
-
204
- "custom": custom_prompt
205
- }
206
 
207
- if analysis_type == "custom" and not custom_prompt.strip():
208
- return "Please provide a custom prompt for analysis."
 
209
 
210
- prompt_text = base_prompts.get(analysis_type, base_prompts["review"])
 
 
 
 
 
 
 
 
 
 
 
 
211
 
212
- full_prompt = f"""{prompt_text}
 
 
213
 
214
- Code:
215
- ```python
216
- {code_content}
217
- ```
 
 
 
218
 
219
- Please provide a detailed response and if fixes are needed, provide the complete corrected code without any truncation."""
220
-
221
- return self.call_claude(full_prompt, max_tokens=8000)
 
 
222
 
223
- def generate_code_with_chat(self, description: str, language: str = "python", reference_files: str = "", chat_history: List = None) -> Tuple[str, List]:
224
- """Generate code with chat functionality for continuation and modifications."""
225
- if chat_history is None:
226
- chat_history = []
227
-
228
- # If this is the first generation, do the standard generation
229
- if not chat_history:
230
- result = self.generate_code(description, language, reference_files)
231
- chat_history.append(("Initial Generation Request", description))
232
- chat_history.append(("Generated Code", result))
233
- return result, chat_history
234
- else:
235
- # This is a follow-up request (continue, modify, etc.)
236
- context = ""
237
- if chat_history:
238
- context = "\n\nPrevious generation conversation:\n"
239
- for i, (q, a) in enumerate(chat_history[-4:]): # Last 4 exchanges for context
240
- context += f"Step {i+1}: {q}\nResponse {i+1}: {a}\n"
241
-
242
- prompt = f"""Based on the previous code generation context:
243
  {context}
244
 
245
- New request: {description}
246
 
247
- Please provide the requested modification/continuation. If you're continuing code, make sure to provide the complete implementation. If you're modifying existing code, provide the full modified version."""
 
 
 
248
 
249
- response = self.call_claude(prompt, max_tokens=8000)
250
- chat_history.append((description, response))
251
- return response, chat_history
252
-
253
- def generate_code(self, description: str, language: str = "python", reference_files: str = "") -> str:
254
- """Generate code based on description with optional reference files."""
255
- reference_context = ""
256
- if reference_files.strip():
257
- reference_context = f"""
258
-
259
- Reference files for context:
260
- ```
261
- {reference_files}
262
- ```
263
-
264
- Please use these files as reference when generating the new code."""
265
-
266
- prompt = f"""Please generate {language} code based on this description:
267
 
268
- {description}
 
 
 
 
 
 
 
269
 
270
- Requirements:
271
- 1. Write clean, well-documented code
272
- 2. Include error handling
273
- 3. Add type hints where appropriate
274
- 4. Provide usage examples
275
- 5. Follow best practices
276
- 6. Generate complete, comprehensive code - don't truncate or abbreviate
277
- 7. If the code is large, provide the full implementation
278
- {reference_context}
279
 
280
- Please provide the complete, ready-to-use code with detailed comments. Make sure to generate comprehensive code that fully implements the requested functionality."""
281
-
282
- return self.call_claude(prompt, max_tokens=8000)
283
 
284
- def chat_with_code(self, code_content: str, question: str, chat_history: List = None) -> Tuple[str, List]:
285
- """Chat about specific code with history and support for long responses."""
286
- if chat_history is None:
287
- chat_history = []
288
-
289
- # Add context from previous conversation
290
- context = ""
291
- if chat_history:
292
- context = "\n\nPrevious conversation:\n"
293
- for i, (q, a) in enumerate(chat_history[-3:]): # Last 3 exchanges for context
294
- context += f"Q{i+1}: {q}\nA{i+1}: {a}\n"
295
-
296
- prompt = f"""Given this code:
297
 
298
- ```python
299
- {code_content}
300
- ```
301
  {context}
302
 
303
- Current question: {question}
304
 
305
- Please provide a detailed answer about the code. If you're suggesting changes or providing code, make sure to include the complete implementation without truncation."""
306
-
307
- response = self.call_claude(prompt, max_tokens=8000)
308
-
309
- # Update chat history
310
- chat_history.append((question, response))
311
-
312
- return response, chat_history
 
313
 
314
- def create_downloadable_file(self, content: str, filename: str = "generated_code.py") -> str:
 
 
 
 
 
 
315
  """Create a downloadable file with the given content."""
316
  timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
317
  filename = f"{timestamp}_{filename}"
318
 
319
- # Create temporary file
320
  temp_file = tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False)
321
  temp_file.write(content)
322
  temp_file.close()
@@ -326,442 +221,496 @@ Please provide a detailed answer about the code. If you're suggesting changes or
326
  # Initialize the copilot
327
  copilot = CodingCopilot()
328
 
329
- # Custom CSS for black and red theme
330
- custom_css = """
 
331
  .gradio-container {
332
- background: linear-gradient(135deg, #0a0a0a 0%, #1a0a0a 100%) !important;
333
- color: #ffffff !important;
 
 
334
  }
335
 
336
- .dark {
337
- background: #0a0a0a !important;
338
- color: #ffffff !important;
 
 
 
339
  }
340
 
341
- /* Tab styling */
342
- .tab-nav {
343
- background: #1a1a1a !important;
344
- border-bottom: 2px solid #dc2626 !important;
 
 
345
  }
346
 
347
- .tab-nav button {
348
- background: #2a2a2a !important;
349
- color: #ffffff !important;
350
- border: 1px solid #dc2626 !important;
351
- margin-right: 5px !important;
352
  }
353
 
354
- .tab-nav button[aria-selected="true"] {
355
- background: #dc2626 !important;
356
- color: #ffffff !important;
 
 
 
 
 
357
  }
358
 
359
- /* Input styling */
360
- .gr-textbox, .gr-dropdown, .gr-file {
361
- background: #2a2a2a !important;
362
- border: 1px solid #dc2626 !important;
363
- color: #ffffff !important;
364
  }
365
 
366
- .gr-textbox:focus, .gr-dropdown:focus {
367
- border-color: #ef4444 !important;
368
- box-shadow: 0 0 0 2px rgba(220, 38, 38, 0.2) !important;
369
  }
370
 
371
- /* Button styling */
372
- .gr-button {
373
- background: linear-gradient(135deg, #dc2626 0%, #b91c1c 100%) !important;
374
- border: none !important;
375
- color: #ffffff !important;
376
- font-weight: bold !important;
377
- transition: all 0.3s ease !important;
378
  }
379
 
380
- .gr-button:hover {
381
- background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%) !important;
382
- transform: translateY(-2px) !important;
383
- box-shadow: 0 5px 15px rgba(220, 38, 38, 0.4) !important;
 
 
384
  }
385
 
386
- /* Code block styling */
387
- .gr-code {
388
- background: #1a1a1a !important;
389
- border: 1px solid #dc2626 !important;
390
  }
391
 
392
- /* Panel styling */
393
- .gr-panel {
394
- background: #1a1a1a !important;
395
- border: 1px solid #333333 !important;
 
 
 
396
  }
397
 
398
- /* Markdown styling */
399
- .gr-markdown {
400
- color: #ffffff !important;
 
401
  }
402
 
403
- .gr-markdown h1 {
404
- color: #dc2626 !important;
405
- text-shadow: 0 0 10px rgba(220, 38, 38, 0.5) !important;
 
 
 
 
 
 
406
  }
407
 
408
- .gr-markdown h2, .gr-markdown h3 {
409
- color: #ef4444 !important;
 
410
  }
411
 
412
- /* File upload styling */
413
- .gr-file-upload {
414
- background: #2a2a2a !important;
415
- border: 2px dashed #dc2626 !important;
416
- color: #ffffff !important;
 
 
 
 
 
 
417
  }
418
 
419
- .gr-file-upload:hover {
420
- border-color: #ef4444 !important;
421
- background: #3a2a2a !important;
422
  }
423
 
424
- /* Chat history styling */
425
- .chat-history {
426
- background: #1a1a1a !important;
427
- border: 1px solid #dc2626 !important;
 
 
 
 
 
428
  border-radius: 8px !important;
429
- padding: 10px !important;
430
- max-height: 400px !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
431
  overflow-y: auto !important;
432
  }
433
 
434
- .chat-message {
435
- margin: 10px 0 !important;
436
- padding: 8px !important;
437
- border-left: 3px solid #dc2626 !important;
438
- background: #2a2a2a !important;
439
  }
440
- """
441
 
442
- def analyze_uploaded_code(files, analysis_type, custom_prompt, chat_history):
443
- """Analyze uploaded code files with chat functionality and long response support."""
444
- if not files:
445
- return "Please upload at least one file.", chat_history, ""
 
 
446
 
447
- content, status = copilot.process_multiple_files(files)
448
- if not content or content.startswith("Error"):
449
- return status or content, chat_history, ""
 
450
 
451
- if chat_history is None:
452
- chat_history = []
 
453
 
454
- # Check if this is initial analysis or follow-up chat
455
- if not chat_history and analysis_type != "chat":
456
- # Initial analysis
457
- result = copilot.analyze_code(content, analysis_type, custom_prompt)
458
- chat_history.append((f"Initial {analysis_type} analysis", result))
459
- status_with_result = f"**Status:** {status}\n\n**Analysis Result:**\n{result}"
460
- else:
461
- # Follow-up chat or direct chat
462
- if not custom_prompt.strip():
463
- return "Please ask a question about the analyzed code.", chat_history, ""
464
-
465
- result, chat_history = copilot.analyze_code_with_chat(content, analysis_type, custom_prompt, chat_history)
466
- status_with_result = result
467
 
468
- # Format chat history for display
469
- chat_display = ""
470
- for i, (q, a) in enumerate(chat_history):
471
- chat_display += f"**Q{i+1}:** {q}\n\n**A{i+1}:** {a}\n\n---\n\n"
472
-
473
- return status_with_result, chat_history, chat_display
474
 
475
- def generate_new_code_with_chat(description, language, reference_files, generation_chat_history):
476
- """Generate new code with chat support for continuation and modifications."""
477
- if not description.strip():
478
- return "Please provide a description of what you want to generate.", None, generation_chat_history, ""
479
-
480
- reference_content = ""
481
- if reference_files:
482
- reference_content, _ = copilot.process_multiple_files(reference_files)
483
-
484
- if generation_chat_history is None:
485
- generation_chat_history = []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
486
 
487
- # Check if this is initial generation or continuation
488
- if not generation_chat_history:
489
- # Initial generation
490
- result = copilot.generate_code(description, language, reference_content)
491
- generation_chat_history.append(("Initial Generation", description))
492
- generation_chat_history.append(("Generated Code", result))
493
- else:
494
- # Continuation or modification
495
- result, generation_chat_history = copilot.generate_code_with_chat(description, language, reference_content, generation_chat_history)
496
 
497
- # Create downloadable file
498
- filename = f"generated_{language}_code.py"
499
- temp_file = copilot.create_downloadable_file(result, filename)
 
500
 
501
- # Format chat history for display
502
- chat_display = ""
503
- for i, (q, a) in enumerate(generation_chat_history):
504
- chat_display += f"**Step {i+1}:** {q}\n\n**Response {i+1}:** {a}\n\n---\n\n"
505
 
506
- return result, temp_file, generation_chat_history, chat_display
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
507
 
508
- def chat_about_code(files, question, chat_history):
509
- """Chat about uploaded code with history and long response support."""
510
- if not files:
511
- return "Please upload at least one file.", chat_history, "", None
512
-
513
- if not question.strip():
514
- return "Please ask a question about the code.", chat_history, "", None
515
-
516
- content, status = copilot.process_multiple_files(files)
517
- if not content or content.startswith("Error"):
518
- return status or content, chat_history, "", None
519
 
520
- if chat_history is None:
521
- chat_history = []
522
 
523
- response, updated_history = copilot.chat_with_code(content, question, chat_history)
 
 
 
 
 
 
 
524
 
525
- # Format chat history for display
526
- chat_display = ""
527
- for i, (q, a) in enumerate(updated_history):
528
- chat_display += f"**Q{i+1}:** {q}\n\n**A{i+1}:** {a}\n\n---\n\n"
529
 
530
- # Create downloadable response file if it contains code
531
- download_file = None
532
- if "```" in response:
533
- download_file = copilot.create_downloadable_file(response, "chat_response.md")
534
-
535
- return response, updated_history, chat_display, download_file
536
-
537
- # Create Gradio interface with custom theme
538
- with gr.Blocks(title="πŸ”₯ Advanced Coding Copilot - Long Code Support", css=custom_css, theme=gr.themes.Base()) as app:
539
- gr.Markdown("""
540
- # πŸ”₯ Advanced Coding Copilot - Long Code Support
541
- ### Upload multiple Python files (.py) or Jupyter notebooks (.ipynb) for intelligent analysis, or generate new code with AI assistance!
542
- ### ✨ **NEW**: Support for extremely long code generation (up to 5000+ lines) with chat continuation!
 
 
 
 
 
 
 
 
 
 
 
 
543
  """)
544
 
545
- with gr.Tabs():
546
- # Enhanced File Analysis Tab
547
- with gr.TabItem("πŸ“ Analyze Code"):
548
- gr.Markdown("### Upload multiple files and get comprehensive analysis with chat support")
549
- with gr.Row():
550
- with gr.Column(scale=1):
551
- file_input = gr.File(
552
- label="πŸ“‚ Upload Multiple Files (.py/.ipynb)",
553
- file_count="multiple",
554
- file_types=[".py", ".ipynb"],
555
- height=120
556
- )
557
- analysis_type = gr.Dropdown(
558
- choices=["review", "explain", "optimize", "debug", "document", "custom", "chat"],
559
- value="review",
560
- label="πŸ” Analysis Type"
561
- )
562
- custom_prompt = gr.Textbox(
563
- label="✏️ Custom Prompt / Chat Message",
564
- lines=3,
565
- placeholder="Write your custom analysis prompt, ask questions, or request 'continue' for more details...",
566
- visible=False
567
- )
568
- analyze_btn = gr.Button("πŸš€ Analyze Code", variant="primary", size="lg")
569
- clear_analysis_btn = gr.Button("πŸ—‘οΈ Clear Analysis Chat", variant="secondary")
570
-
571
- with gr.Column(scale=2):
572
- analysis_output = gr.Textbox(
573
- label="πŸ“Š Analysis Result / Current Response",
574
- lines=15,
575
- max_lines=30
576
- )
577
- analysis_chat_history = gr.Textbox(
578
- label="πŸ’¬ Analysis Chat History",
579
- lines=15,
580
- max_lines=30,
581
- placeholder="Chat history will appear here after analysis..."
582
- )
583
-
584
- # Hidden state for analysis chat history
585
- analysis_chat_state = gr.State([])
586
-
587
- # Show/hide custom prompt based on analysis type
588
- def toggle_custom_prompt_analysis(analysis_type):
589
- if analysis_type in ["custom", "chat"]:
590
- return gr.update(visible=True, label="✏️ Custom Prompt" if analysis_type == "custom" else "πŸ’¬ Chat Message")
591
- return gr.update(visible=False)
592
-
593
- def clear_analysis_chat():
594
- return [], "", ""
595
-
596
- def update_button_text(analysis_type):
597
- if analysis_type == "chat":
598
- return gr.update(value="πŸ’­ Send Message")
599
- return gr.update(value="πŸš€ Analyze Code")
600
-
601
- analysis_type.change(
602
- toggle_custom_prompt_analysis,
603
- inputs=analysis_type,
604
- outputs=custom_prompt
605
- )
606
- analysis_type.change(
607
- update_button_text,
608
- inputs=analysis_type,
609
- outputs=analyze_btn
610
- )
611
-
612
- analyze_btn.click(
613
- analyze_uploaded_code,
614
- inputs=[file_input, analysis_type, custom_prompt, analysis_chat_state],
615
- outputs=[analysis_output, analysis_chat_state, analysis_chat_history]
616
- )
617
-
618
- clear_analysis_btn.click(
619
- clear_analysis_chat,
620
- outputs=[analysis_chat_state, analysis_chat_history, analysis_output]
621
- )
622
 
623
- # Enhanced Code Generation Tab with Chat Support
624
- with gr.TabItem("⚑ Generate Code"):
625
- gr.Markdown("### Generate new code with chat support for continuation and modifications")
626
- with gr.Row():
627
- with gr.Column(scale=1):
628
- code_description = gr.Textbox(
629
- label="πŸ“ Describe what you want to code / Chat Message",
630
- lines=5,
631
- placeholder="E.g., Create a REST API using FastAPI... OR 'continue the previous code' OR 'add more features' OR 'optimize the generated code'"
632
- )
633
- code_language = gr.Dropdown(
634
- choices=["python", "javascript", "java", "cpp", "c", "go", "rust"],
635
- value="python",
636
- label="πŸ’» Programming Language"
637
- )
638
- reference_files = gr.File(
639
- label="πŸ“š Reference Files (optional)",
640
- file_count="multiple",
641
- file_types=[".py", ".ipynb"]
642
- )
643
- generate_btn = gr.Button("🎯 Generate/Continue Code", variant="primary", size="lg")
644
- clear_generation_btn = gr.Button("πŸ—‘οΈ Clear Generation Chat", variant="secondary")
645
-
646
- with gr.Column(scale=2):
647
- generated_code = gr.Code(
648
- label="πŸ”§ Generated Code",
649
- language="python",
650
- lines=25,
651
- max_lines=50
652
- )
653
- generation_chat_history = gr.Textbox(
654
- label="πŸ’¬ Generation Chat History",
655
- lines=10,
656
- max_lines=20,
657
- placeholder="Generation history will appear here..."
658
- )
659
- download_generated = gr.File(
660
- label="πŸ’Ύ Download Generated Code",
661
- visible=False,
662
- interactive=False
663
- )
664
-
665
- # Hidden state for generation chat history
666
- generation_chat_state = gr.State([])
667
-
668
- def clear_generation_chat():
669
- return [], "", ""
670
-
671
- generate_btn.click(
672
- generate_new_code_with_chat,
673
- inputs=[code_description, code_language, reference_files, generation_chat_state],
674
- outputs=[generated_code, download_generated, generation_chat_state, generation_chat_history]
675
  )
676
 
677
- clear_generation_btn.click(
678
- clear_generation_chat,
679
- outputs=[generation_chat_state, generation_chat_history, generated_code]
680
- )
681
-
682
- # Enhanced Code Chat Tab
683
- with gr.TabItem("πŸ’¬ Chat About Code"):
684
- gr.Markdown("### Interactive chat about your code with conversation history and long response support")
685
  with gr.Row():
686
  with gr.Column(scale=1):
687
- chat_file_input = gr.File(
688
- label="πŸ“‚ Upload Code Files",
 
689
  file_count="multiple",
690
  file_types=[".py", ".ipynb"],
691
- height=120
692
- )
693
- code_question = gr.Textbox(
694
- label="❓ Ask a question about your code",
695
- lines=3,
696
- placeholder="E.g., How can I optimize this algorithm? What design patterns are used here? Continue explaining... Add more features..."
697
  )
698
- chat_btn = gr.Button("πŸ’­ Ask Question", variant="primary", size="lg")
699
- clear_chat_btn = gr.Button("πŸ—‘οΈ Clear Chat History", variant="secondary")
700
 
701
- with gr.Column(scale=2):
702
- chat_output = gr.Textbox(
703
- label="πŸ€– AI Response",
704
- lines=15,
705
- max_lines=30
706
- )
707
- chat_history_display = gr.Textbox(
708
- label="πŸ“œ Chat History",
709
- lines=10,
710
- max_lines=25
711
- )
712
- download_chat = gr.File(
713
- label="πŸ’Ύ Download Chat Response",
714
- visible=False,
715
- interactive=False
716
  )
717
-
718
- # Hidden state for chat history
719
- chat_history_state = gr.State([])
720
-
721
- def handle_chat(files, question, history):
722
- response, updated_history, history_display, download_file = chat_about_code(files, question, history)
723
- download_visible = download_file is not None
724
- return (
725
- response,
726
- updated_history,
727
- history_display,
728
- gr.update(value=download_file, visible=download_visible),
729
- "" # Clear the question input
730
- )
731
-
732
- def clear_chat():
733
- return [], "", ""
734
-
735
- chat_btn.click(
736
- handle_chat,
737
- inputs=[chat_file_input, code_question, chat_history_state],
738
- outputs=[chat_output, chat_history_state, chat_history_display, download_chat, code_question]
739
- )
740
-
741
- clear_chat_btn.click(
742
- clear_chat,
743
- outputs=[chat_history_state, chat_history_display, chat_output]
744
- )
 
 
 
 
 
 
 
745
 
746
- # Enhanced Footer
747
- gr.Markdown("""
748
- ---
749
- ### πŸ”₯ Features:
750
- - **πŸš€ Long Code Support**: Generate up to 5000+ lines of code with continuation support
751
- - **πŸ’¬ Chat Continuation**: Ask "continue", "add more features", or "extend the code" in any tab
752
- - **Multi-file Support**: Upload and analyze multiple files simultaneously
753
- - **Custom Prompts**: Write your own analysis prompts for specific needs
754
- - **Interactive Chat**: Have conversations about your code with full history
755
- - **File Downloads**: Get generated code and chat responses as downloadable files
756
- - **Reference Context**: Use existing files as reference when generating new code
757
 
758
- ### πŸ’‘ Pro Tips:
759
- - Use "continue" or "continue the code" to extend generated code
760
- - Ask "add more features" to enhance existing implementations
761
- - Use "optimize" or "refactor" to improve code quality
762
- - Upload reference files to generate code based on existing patterns
763
 
764
- **Powered by:** Claude 3 Haiku via AWS Bedrock | **Theme:** Cyberpunk Black & Red | **Max Tokens:** 8000 per response
 
 
 
 
 
765
  """)
766
 
767
  # Launch the app
@@ -770,5 +719,6 @@ if __name__ == "__main__":
770
  server_name="0.0.0.0",
771
  server_port=7860,
772
  share=True,
773
- show_error=True
 
774
  )
 
14
  def __init__(self):
15
  """Initialize the coding copilot with AWS Bedrock client."""
16
  self.setup_aws_client()
 
17
 
18
  def setup_aws_client(self):
19
  """Setup AWS Bedrock client with credentials from environment variables."""
 
22
  'bedrock-runtime',
23
  aws_access_key_id=os.getenv('AWS_ACCESS_KEY_ID'),
24
  aws_secret_access_key=os.getenv('AWS_SECRET_ACCESS_KEY'),
25
+ region_name='us-east-1'
26
  )
27
  except Exception as e:
28
  print(f"Error setting up AWS client: {e}")
 
31
  def call_claude(self, prompt: str, max_tokens: int = 8000) -> str:
32
  """Call Claude 3 Haiku via AWS Bedrock with increased token limit."""
33
  if not self.bedrock_client:
34
+ return "❌ **Error**: AWS Bedrock client not initialized. Please check your credentials."
35
 
36
  try:
 
37
  body = {
38
  "anthropic_version": "bedrock-2023-05-31",
39
  "max_tokens": max_tokens,
40
+ "messages": [{"role": "user", "content": prompt}],
 
 
 
 
 
41
  "temperature": 0.1,
42
  "top_p": 0.9,
43
  }
 
53
  return response_body['content'][0]['text']
54
 
55
  except Exception as e:
56
+ return f"❌ **Error calling Claude**: {str(e)}"
57
 
58
  def read_python_file(self, file_path: str) -> str:
59
  """Read content from a Python file."""
 
74
  if cell.cell_type == 'code':
75
  code_cells.append(f"# Cell {len(code_cells) + 1}")
76
  code_cells.append(cell.source)
77
+ code_cells.append("")
78
 
79
  return '\n'.join(code_cells)
80
  except Exception as e:
81
  return f"Error reading notebook: {str(e)}"
82
 
83
+ def process_files(self, files: List) -> Tuple[str, str]:
84
+ """Process uploaded files and return combined content."""
85
  if not files:
86
  return "", "No files uploaded"
87
 
 
101
  continue
102
 
103
  if content and not content.startswith("Error"):
104
+ all_content.append(f"# πŸ“ File: {file_name}")
105
+ all_content.append(f"# πŸ“„ Type: {file_extension}")
106
  all_content.append("# " + "="*50)
107
  all_content.append(content)
108
  all_content.append("\n" + "="*60 + "\n")
109
+ file_info.append(f"{file_name}")
110
 
111
  combined_content = '\n'.join(all_content)
112
+ status = f"βœ… Successfully loaded {len(file_info)} files: {', '.join(file_info)}"
113
 
114
  return combined_content, status
115
 
116
+ def process_message(self, message: str, files: List = None, history: List = None) -> str:
117
+ """Process user message with advanced context handling for long code generation."""
118
+ if history is None:
119
+ history = []
120
 
121
+ # Process files if provided
122
+ file_content = ""
123
+ file_status = ""
124
+ if files:
125
+ file_content, file_status = self.process_files(files)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
 
127
+ # Detect continuation requests
128
+ continue_keywords = ['continue', 'continue the code', 'continue from where', 'keep going', 'add more', 'extend', 'complete the']
129
+ is_continuation = any(keyword in message.lower() for keyword in continue_keywords)
130
 
131
+ # Build comprehensive context from history
132
+ context = ""
133
+ if history:
134
+ if is_continuation:
135
+ # For continuation, include more context (last 5 exchanges)
136
+ context = "\n\nFull conversation context for continuation:\n"
137
+ for i, (user_msg, assistant_msg) in enumerate(history[-5:]):
138
+ context += f"Exchange {i+1}:\nUser: {user_msg}\nAssistant: {assistant_msg}\n\n"
139
+ else:
140
+ # For new topics, include recent context (last 3 exchanges)
141
+ context = "\n\nRecent conversation context:\n"
142
+ for i, (user_msg, assistant_msg) in enumerate(history[-3:]):
143
+ context += f"User: {user_msg}\nAssistant: {assistant_msg}\n\n"
144
 
145
+ # Build specialized prompts based on request type
146
+ if is_continuation:
147
+ prompt = f"""You are an advanced coding assistant. The user is asking you to CONTINUE or EXTEND previous code.
148
 
149
+ CRITICAL INSTRUCTIONS FOR CONTINUATION:
150
+ 1. Look at the previous conversation to understand what code was generated
151
+ 2. Continue from where the previous code left off - DO NOT start from the beginning
152
+ 3. Maintain the same coding style, structure, and patterns
153
+ 4. Add new functionality or complete incomplete sections
154
+ 5. Generate substantial code (aim for 500-2000+ lines if needed)
155
+ 6. Ensure the continuation integrates seamlessly with previous code
156
 
157
+ User's continuation request: {message}
158
+
159
+ {file_status}
160
+
161
+ {f"Code files content for reference:\n```\n{file_content}\n```" if file_content else ""}
162
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
163
  {context}
164
 
165
+ 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."""
166
 
167
+ else:
168
+ # Determine if this is a code generation request
169
+ generation_keywords = ['create', 'generate', 'build', 'make', 'develop', 'write code', 'implement', 'design']
170
+ is_generation = any(keyword in message.lower() for keyword in generation_keywords)
171
 
172
+ if is_generation:
173
+ prompt = f"""You are an advanced coding assistant specialized in generating comprehensive, production-ready code.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
174
 
175
+ CRITICAL INSTRUCTIONS FOR CODE GENERATION:
176
+ 1. Generate COMPLETE, COMPREHENSIVE code - aim for 500-3000+ lines when appropriate
177
+ 2. Include ALL necessary components: classes, functions, error handling, documentation
178
+ 3. Create fully functional, production-ready applications
179
+ 4. Add comprehensive comments and docstrings
180
+ 5. Include proper imports, dependencies, and structure
181
+ 6. Don't truncate or abbreviate - provide the FULL implementation
182
+ 7. If the project is large, focus on core functionality but make it complete
183
 
184
+ User's request: {message}
 
 
 
 
 
 
 
 
185
 
186
+ {file_status}
 
 
187
 
188
+ {f"Reference code files:\n```\n{file_content}\n```" if file_content else ""}
 
 
 
 
 
 
 
 
 
 
 
 
189
 
 
 
 
190
  {context}
191
 
192
+ Generate comprehensive, complete code that fully implements the requested functionality. Provide extensive code with proper structure, documentation, and all necessary components."""
193
 
194
+ else:
195
+ # Regular analysis/chat prompt
196
+ prompt = f"""You are an advanced coding assistant. Provide detailed, comprehensive responses.
197
+
198
+ User's request: {message}
199
+
200
+ {file_status}
201
+
202
+ {f"Code files content:\n```\n{file_content}\n```" if file_content else ""}
203
 
204
+ {context}
205
+
206
+ Provide a thorough and helpful response. If suggesting code changes, provide complete implementations."""
207
+
208
+ return self.call_claude(prompt, max_tokens=8000)
209
+
210
+ def create_download_file(self, content: str, filename: str = "code_output.py") -> str:
211
  """Create a downloadable file with the given content."""
212
  timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
213
  filename = f"{timestamp}_{filename}"
214
 
 
215
  temp_file = tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False)
216
  temp_file.write(content)
217
  temp_file.close()
 
221
  # Initialize the copilot
222
  copilot = CodingCopilot()
223
 
224
+ # Professional ChatGPT-style CSS
225
+ chatgpt_css = """
226
+ /* Global Styles */
227
  .gradio-container {
228
+ max-width: 1200px !important;
229
+ margin: 0 auto !important;
230
+ background: #ffffff !important;
231
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif !important;
232
  }
233
 
234
+ /* Header Styles */
235
+ .header-container {
236
+ background: linear-gradient(90deg, #10a37f 0%, #1a7f64 100%) !important;
237
+ padding: 1rem 2rem !important;
238
+ margin: -1rem -1rem 1rem -1rem !important;
239
+ border-radius: 0 !important;
240
  }
241
 
242
+ .header-title {
243
+ color: white !important;
244
+ font-size: 1.5rem !important;
245
+ font-weight: 600 !important;
246
+ margin: 0 !important;
247
+ text-align: center !important;
248
  }
249
 
250
+ .header-subtitle {
251
+ color: rgba(255, 255, 255, 0.9) !important;
252
+ font-size: 0.9rem !important;
253
+ text-align: center !important;
254
+ margin: 0.5rem 0 0 0 !important;
255
  }
256
 
257
+ /* Chat Interface */
258
+ .chat-container {
259
+ background: #ffffff !important;
260
+ border-radius: 8px !important;
261
+ border: 1px solid #e5e5e5 !important;
262
+ max-height: 600px !important;
263
+ overflow-y: auto !important;
264
+ padding: 0 !important;
265
  }
266
 
267
+ .chatbot {
268
+ background: transparent !important;
269
+ border: none !important;
 
 
270
  }
271
 
272
+ .message {
273
+ padding: 1rem 1.5rem !important;
274
+ border-bottom: 1px solid #f0f0f0 !important;
275
  }
276
 
277
+ .message:last-child {
278
+ border-bottom: none !important;
 
 
 
 
 
279
  }
280
 
281
+ .user-message {
282
+ background: #f8f9fa !important;
283
+ margin: 0.5rem 0 !important;
284
+ padding: 0.75rem 1rem !important;
285
+ border-radius: 8px !important;
286
+ border: 1px solid #e9ecef !important;
287
  }
288
 
289
+ .bot-message {
290
+ background: transparent !important;
291
+ margin: 0.5rem 0 !important;
292
+ padding: 0.75rem 1rem !important;
293
  }
294
 
295
+ /* Input Area */
296
+ .input-container {
297
+ background: #ffffff !important;
298
+ border: 1px solid #d1d5db !important;
299
+ border-radius: 12px !important;
300
+ padding: 0.5rem !important;
301
+ margin-top: 1rem !important;
302
  }
303
 
304
+ .input-row {
305
+ display: flex !important;
306
+ align-items: flex-end !important;
307
+ gap: 0.5rem !important;
308
  }
309
 
310
+ .chat-input {
311
+ flex: 1 !important;
312
+ border: none !important;
313
+ background: transparent !important;
314
+ resize: vertical !important;
315
+ min-height: 24px !important;
316
+ padding: 0.5rem !important;
317
+ font-size: 1rem !important;
318
+ line-height: 1.5 !important;
319
  }
320
 
321
+ .chat-input:focus {
322
+ outline: none !important;
323
+ box-shadow: none !important;
324
  }
325
 
326
+ /* Buttons */
327
+ .send-button {
328
+ background: #10a37f !important;
329
+ color: white !important;
330
+ border: none !important;
331
+ border-radius: 8px !important;
332
+ padding: 0.5rem 1rem !important;
333
+ font-weight: 500 !important;
334
+ cursor: pointer !important;
335
+ transition: background-color 0.2s ease !important;
336
+ min-width: 80px !important;
337
  }
338
 
339
+ .send-button:hover {
340
+ background: #0d8c6c !important;
 
341
  }
342
 
343
+ .send-button:disabled {
344
+ background: #9ca3af !important;
345
+ cursor: not-allowed !important;
346
+ }
347
+
348
+ .secondary-button {
349
+ background: #f3f4f6 !important;
350
+ color: #374151 !important;
351
+ border: 1px solid #d1d5db !important;
352
  border-radius: 8px !important;
353
+ padding: 0.5rem 1rem !important;
354
+ font-weight: 500 !important;
355
+ cursor: pointer !important;
356
+ transition: all 0.2s ease !important;
357
+ }
358
+
359
+ .secondary-button:hover {
360
+ background: #e5e7eb !important;
361
+ border-color: #9ca3af !important;
362
+ }
363
+
364
+ /* File Upload Area */
365
+ .file-upload-area {
366
+ background: #f9fafb !important;
367
+ border: 2px dashed #d1d5db !important;
368
+ border-radius: 8px !important;
369
+ padding: 1rem !important;
370
+ text-align: center !important;
371
+ transition: all 0.2s ease !important;
372
+ margin-bottom: 1rem !important;
373
+ }
374
+
375
+ .file-upload-area:hover {
376
+ border-color: #10a37f !important;
377
+ background: #f0fdf4 !important;
378
+ }
379
+
380
+ .file-upload-text {
381
+ color: #6b7280 !important;
382
+ font-size: 0.9rem !important;
383
+ }
384
+
385
+ /* Status and Info */
386
+ .status-message {
387
+ background: #f0f9ff !important;
388
+ border: 1px solid #7dd3fc !important;
389
+ border-radius: 6px !important;
390
+ padding: 0.75rem !important;
391
+ margin: 0.5rem 0 !important;
392
+ font-size: 0.9rem !important;
393
+ color: #0c4a6e !important;
394
+ }
395
+
396
+ .error-message {
397
+ background: #fef2f2 !important;
398
+ border: 1px solid #fecaca !important;
399
+ border-radius: 6px !important;
400
+ padding: 0.75rem !important;
401
+ margin: 0.5rem 0 !important;
402
+ font-size: 0.9rem !important;
403
+ color: #991b1b !important;
404
+ }
405
+
406
+ /* Code blocks */
407
+ .code-block {
408
+ background: #f8f9fa !important;
409
+ border: 1px solid #e9ecef !important;
410
+ border-radius: 6px !important;
411
+ padding: 1rem !important;
412
+ font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace !important;
413
+ font-size: 0.9rem !important;
414
+ line-height: 1.4 !important;
415
+ overflow-x: auto !important;
416
+ }
417
+
418
+ /* Sidebar */
419
+ .sidebar {
420
+ background: #f8f9fa !important;
421
+ border-right: 1px solid #e5e5e5 !important;
422
+ padding: 1rem !important;
423
+ height: 100vh !important;
424
  overflow-y: auto !important;
425
  }
426
 
427
+ .sidebar-title {
428
+ font-weight: 600 !important;
429
+ color: #374151 !important;
430
+ margin-bottom: 1rem !important;
431
+ font-size: 1.1rem !important;
432
  }
 
433
 
434
+ /* Mobile Responsiveness */
435
+ @media (max-width: 768px) {
436
+ .gradio-container {
437
+ margin: 0 !important;
438
+ padding: 0.5rem !important;
439
+ }
440
 
441
+ .header-container {
442
+ margin: -0.5rem -0.5rem 1rem -0.5rem !important;
443
+ padding: 1rem !important;
444
+ }
445
 
446
+ .chat-container {
447
+ max-height: 500px !important;
448
+ }
449
 
450
+ .input-row {
451
+ flex-direction: column !important;
452
+ gap: 0.75rem !important;
453
+ }
 
 
 
 
 
 
 
 
 
454
 
455
+ .send-button {
456
+ width: 100% !important;
457
+ }
458
+ }
 
 
459
 
460
+ /* Loading animation */
461
+ .loading {
462
+ display: inline-block !important;
463
+ width: 20px !important;
464
+ height: 20px !important;
465
+ border: 3px solid #f3f3f3 !important;
466
+ border-top: 3px solid #10a37f !important;
467
+ border-radius: 50% !important;
468
+ animation: spin 1s linear infinite !important;
469
+ }
470
+
471
+ @keyframes spin {
472
+ 0% { transform: rotate(0deg); }
473
+ 100% { transform: rotate(360deg); }
474
+ }
475
+
476
+ /* Hide default gradio elements */
477
+ .gradio-container .gr-button {
478
+ transition: all 0.2s ease !important;
479
+ }
480
+
481
+ /* Custom scrollbar */
482
+ .chat-container::-webkit-scrollbar {
483
+ width: 6px !important;
484
+ }
485
+
486
+ .chat-container::-webkit-scrollbar-track {
487
+ background: #f1f1f1 !important;
488
+ }
489
+
490
+ .chat-container::-webkit-scrollbar-thumb {
491
+ background: #c1c1c1 !important;
492
+ border-radius: 3px !important;
493
+ }
494
+
495
+ .chat-container::-webkit-scrollbar-thumb:hover {
496
+ background: #a1a1a1 !important;
497
+ }
498
+ """
499
+
500
+ def process_chat_message(message, files, history):
501
+ """Process a new chat message with advanced continuation support."""
502
+ if not message.strip() and not files:
503
+ return history, history, ""
504
 
505
+ # Add user message to history
506
+ if history is None:
507
+ history = []
 
 
 
 
 
 
508
 
509
+ user_msg = message
510
+ if files:
511
+ file_names = [os.path.basename(f.name) for f in files]
512
+ user_msg += f" πŸ“ *[Uploaded: {', '.join(file_names)}]*"
513
 
514
+ # Special handling for continuation requests
515
+ continue_keywords = ['continue', 'continue the code', 'continue from where', 'keep going', 'add more', 'extend', 'complete the']
516
+ is_continuation = any(keyword in message.lower() for keyword in continue_keywords)
 
517
 
518
+ if is_continuation and history:
519
+ # For continuation, show a status message to user
520
+ status_msg = "πŸ”„ **Continuing from previous code...** (Analyzing context and extending the implementation)"
521
+ temp_history = history + [[user_msg, status_msg]]
522
+
523
+ # Get AI response with full context
524
+ ai_response = copilot.process_message(message, files, history)
525
+
526
+ # Add both messages to history
527
+ history.append([user_msg, ai_response])
528
+
529
+ return history, history, ""
530
+ else:
531
+ # Regular processing
532
+ ai_response = copilot.process_message(message, files, history)
533
+
534
+ # Add both messages to history
535
+ history.append([user_msg, ai_response])
536
+
537
+ return history, history, ""
538
 
539
+ def smart_continue_suggestion(history):
540
+ """Suggest continuation if the last response seems incomplete."""
541
+ if not history:
542
+ return ""
 
 
 
 
 
 
 
543
 
544
+ last_response = history[-1][1] if history else ""
 
545
 
546
+ # Check if response might be incomplete
547
+ incomplete_indicators = [
548
+ "```" in last_response and last_response.count("```") % 2 != 0, # Unclosed code block
549
+ last_response.endswith("..."),
550
+ "# TODO" in last_response,
551
+ "# Continue" in last_response.lower(),
552
+ len(last_response) > 3000 # Very long response might be cut off
553
+ ]
554
 
555
+ if any(incomplete_indicators):
556
+ return "πŸ’‘ **Tip**: Type 'continue' to extend this code or add more functionality!"
 
 
557
 
558
+ return ""
559
+
560
+ def clear_chat():
561
+ """Clear the chat history."""
562
+ return [], []
563
+
564
+ def create_download_from_message(message):
565
+ """Create a downloadable file from the current message if it contains code."""
566
+ if "```" in message:
567
+ # Extract code blocks
568
+ import re
569
+ code_blocks = re.findall(r'```(?:\w+)?\n(.*?)\n```', message, re.DOTALL)
570
+ if code_blocks:
571
+ combined_code = "\n\n".join(code_blocks)
572
+ return copilot.create_download_file(combined_code)
573
+ return None
574
+
575
+ # Create the main interface
576
+ with gr.Blocks(css=chatgpt_css, title="Coding Copilot Pro") as app:
577
+ # Header
578
+ gr.HTML("""
579
+ <div class="header-container">
580
+ <h1 class="header-title">πŸ€– Coding Copilot Pro</h1>
581
+ <p class="header-subtitle">Your AI-powered coding assistant β€’ Powered by Claude 3 Haiku</p>
582
+ </div>
583
  """)
584
 
585
+ # Main chat interface
586
+ with gr.Row():
587
+ with gr.Column(scale=1, min_width=250):
588
+ # Sidebar with features
589
+ gr.HTML('<h3 class="sidebar-title">✨ Features</h3>')
590
+ gr.Markdown("""
591
+ **πŸ’¬ Chat Features:**
592
+ β€’ Long code generation (1000+ lines)
593
+ β€’ Smart continuation support
594
+ β€’ Code analysis & review
595
+ β€’ Bug detection & fixes
596
+ β€’ Code optimization
597
+ β€’ Architecture advice
598
+ β€’ Best practices
599
+
600
+ **πŸ“ File Support:**
601
+ β€’ Python files (.py)
602
+ β€’ Jupyter notebooks (.ipynb)
603
+ β€’ Multiple file upload
604
+
605
+ **πŸ› οΈ Capabilities:**
606
+ β€’ Generate complete applications
607
+ β€’ Continue incomplete code
608
+ β€’ Debug existing code
609
+ β€’ Explain complex algorithms
610
+ β€’ Refactor & optimize
611
+ β€’ Add comprehensive documentation
612
+
613
+ **πŸ’‘ Pro Tips:**
614
+ β€’ Say "continue" to extend code
615
+ β€’ Upload files for context
616
+ β€’ Ask for "complete implementation"
617
+ β€’ Request "production-ready code"
618
+ """)
619
+
620
+ # Quick actions
621
+ gr.HTML('<h3 class="sidebar-title">πŸš€ Quick Actions</h3>')
622
+ with gr.Column():
623
+ quick_review = gr.Button("πŸ“‹ Code Review", size="sm", variant="secondary")
624
+ quick_debug = gr.Button("πŸ› Debug Code", size="sm", variant="secondary")
625
+ quick_optimize = gr.Button("⚑ Optimize", size="sm", variant="secondary")
626
+ quick_explain = gr.Button("πŸ“– Explain Code", size="sm", variant="secondary")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
627
 
628
+ with gr.Column(scale=3):
629
+ # Chat interface
630
+ chatbot = gr.Chatbot(
631
+ height=500,
632
+ show_label=False,
633
+ container=True,
634
+ bubble_full_width=False,
635
+ avatar_images=("πŸ‘€", "πŸ€–")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
636
  )
637
 
638
+ # Input area
 
 
 
 
 
 
 
639
  with gr.Row():
640
  with gr.Column(scale=1):
641
+ # File upload
642
+ files = gr.File(
643
+ label="πŸ“Ž Attach Files",
644
  file_count="multiple",
645
  file_types=[".py", ".ipynb"],
646
+ show_label=False,
647
+ container=False
 
 
 
 
648
  )
 
 
649
 
650
+ with gr.Column(scale=4):
651
+ # Message input
652
+ msg = gr.Textbox(
653
+ label="Message",
654
+ placeholder="Ask me anything about coding... Type 'continue' to extend previous code, or request 'complete implementation' for long code generation",
655
+ show_label=False,
656
+ lines=1,
657
+ max_lines=5
 
 
 
 
 
 
 
658
  )
659
+
660
+ with gr.Column(scale=1, min_width=100):
661
+ # Send and clear buttons
662
+ with gr.Row():
663
+ submit = gr.Button("Send", variant="primary", scale=2)
664
+ clear = gr.Button("πŸ—‘οΈ", variant="secondary", scale=1)
665
+
666
+ # Hidden state for chat history
667
+ chat_history = gr.State([])
668
+
669
+ # Event handlers
670
+ def quick_action(action_type):
671
+ return f"Please {action_type.lower()} the uploaded code files."
672
+
673
+ # Quick action buttons
674
+ quick_review.click(lambda: "Please perform a comprehensive code review of the uploaded files, including quality assessment, potential bugs, performance improvements, and security considerations.", outputs=msg)
675
+ quick_debug.click(lambda: "Please debug the uploaded code thoroughly and identify any issues, bugs, or potential problems with detailed fixes.", outputs=msg)
676
+ quick_optimize.click(lambda: "Please optimize the uploaded code for better performance, readability, and maintainability. Provide the complete optimized version.", outputs=msg)
677
+ quick_explain.click(lambda: "Please provide a detailed explanation of what this code does, how it works, and its key components with examples.", outputs=msg)
678
+
679
+ # Enhanced continuation support
680
+ def handle_submit_with_continuation(message, files, history):
681
+ result_history, result_state, cleared_msg = process_chat_message(message, files, history)
682
+ suggestion = smart_continue_suggestion(result_history)
683
+ return result_history, result_state, cleared_msg, suggestion
684
+
685
+ # Main chat functionality with continuation support
686
+ submit.click(
687
+ handle_submit_with_continuation,
688
+ inputs=[msg, files, chat_history],
689
+ outputs=[chatbot, chat_history, msg, gr.HTML(visible=False)]
690
+ ).then(
691
+ lambda: [None, None], # Clear files after sending
692
+ outputs=[files, msg]
693
+ )
694
 
695
+ # Enter key submission with continuation support
696
+ msg.submit(
697
+ handle_submit_with_continuation,
698
+ inputs=[msg, files, chat_history],
699
+ outputs=[chatbot, chat_history, msg, gr.HTML(visible=False)]
700
+ ).then(
701
+ lambda: [None, None],
702
+ outputs=[files, msg]
703
+ )
 
 
704
 
705
+ # Clear chat
706
+ clear.click(clear_chat, outputs=[chatbot, chat_history])
 
 
 
707
 
708
+ # Footer
709
+ gr.HTML("""
710
+ <div style="text-align: center; padding: 2rem 0; color: #6b7280; font-size: 0.9rem; border-top: 1px solid #e5e7eb; margin-top: 2rem;">
711
+ <p><strong>Coding Copilot Pro</strong> β€’ Built with Claude 3 Haiku via AWS Bedrock</p>
712
+ <p>Upload your code files and start chatting for intelligent analysis, debugging, and optimization</p>
713
+ </div>
714
  """)
715
 
716
  # Launch the app
 
719
  server_name="0.0.0.0",
720
  server_port=7860,
721
  share=True,
722
+ show_error=True,
723
+ show_api=False
724
  )