Nihal2000 commited on
Commit
7b5c169
Β·
1 Parent(s): a48e8b3

feat: Implement Hackathon-Winning UI with 3D Viz and Agent Monitor

Browse files
Files changed (1) hide show
  1. app.py +446 -253
app.py CHANGED
@@ -1,316 +1,509 @@
1
  """
2
- DebugGenie - Streamlined Flow Edition
3
- Intuitive, linear workflow: Input -> Analysis -> Solution.
4
  """
5
  import os
 
6
  import gradio as gr
7
- import asyncio
8
- from theme import debuggenie_theme
9
 
10
- # Check if Modal URL is configured
11
  MODAL_API_URL = os.environ.get("MODAL_API_URL")
12
 
13
- # --- CSS ARCHITECTURE (Streamlined) ---
14
- STREAMLINED_CSS = """
15
- /* πŸŒ‘ Base Styles */
 
 
16
  body {
17
- background-color: #09090b;
18
- color: #f4f4f5;
19
  }
20
 
21
- /* 🟦 Typography */
22
- h1, h2, h3, h4, h5, h6 {
23
- font-family: 'Inter', sans-serif;
24
- font-weight: 600;
25
- letter-spacing: -0.02em;
26
  }
27
 
28
- .code-font {
29
- font-family: 'JetBrains Mono', monospace;
30
  }
31
 
32
- /* πŸŽ›οΈ Components */
33
- .pro-card {
34
- background-color: #18181b !important;
35
- border: 1px solid #27272a !important;
36
- border-radius: 12px !important;
37
- padding: 24px !important;
38
- transition: border-color 0.2s ease;
 
 
 
 
39
  }
40
 
41
- .pro-card:hover {
42
- border-color: #3f3f46 !important;
 
 
 
 
 
 
43
  }
44
 
45
- .input-area textarea {
46
- background-color: #09090b !important;
47
- border: 1px solid #27272a !important;
48
- font-family: 'JetBrains Mono', monospace !important;
49
- font-size: 16px !important;
50
- padding: 16px !important;
51
- border-radius: 12px !important;
52
  }
53
 
54
- .input-area textarea:focus {
55
- border-color: #3b82f6 !important;
56
- box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.2) !important;
 
 
57
  }
58
 
59
- /* 🌊 Flow Containers */
60
- .flow-section {
61
- margin-bottom: 40px;
62
- max-width: 1000px;
63
- margin-left: auto;
64
- margin-right: auto;
 
 
 
65
  }
66
 
67
- .step-number {
68
- display: inline-block;
69
- width: 24px;
70
- height: 24px;
71
- background-color: #27272a;
72
- color: #a1a1aa;
73
- border-radius: 50%;
74
- text-align: center;
75
- line-height: 24px;
76
- font-size: 12px;
77
- margin-right: 8px;
78
- font-weight: bold;
79
  }
80
 
81
- /* 🏷️ Badges */
82
- .badge {
83
- display: inline-flex;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
  align-items: center;
85
- padding: 4px 10px;
86
- border-radius: 6px;
87
- font-size: 12px;
88
  font-weight: 600;
89
- border: 1px solid transparent;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  }
91
 
92
- .badge-success {
93
- background-color: rgba(16, 185, 129, 0.1);
94
- color: #34d399;
95
- border-color: rgba(16, 185, 129, 0.2);
96
  }
97
 
98
- .badge-warning {
99
- background-color: rgba(245, 158, 11, 0.1);
100
- color: #fbbf24;
101
- border-color: rgba(245, 158, 11, 0.2);
102
  }
103
 
104
- /* Header Responsiveness */
105
- .header-container {
 
 
106
  display: flex;
107
  align-items: center;
108
  justify-content: center;
109
- gap: 12px;
110
- margin-bottom: 40px;
111
- padding-top: 20px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
  }
113
 
114
- .logo-icon {
115
- font-size: clamp(24px, 5vw, 32px);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116
  }
117
 
118
- .logo-text h1 {
119
- margin: 0;
120
- font-size: clamp(20px, 4vw, 28px);
121
- color: #f4f4f5;
 
 
122
  }
123
 
124
- .logo-text p {
125
- margin: 0;
126
- font-size: clamp(14px, 2vw, 16px);
127
- color: #a1a1aa;
 
 
 
 
 
 
 
 
 
 
 
128
  }
129
  """
130
 
131
- def create_header():
132
- """Create a centered, minimal header."""
133
- return gr.Markdown("""
134
- <div class="header-container">
135
- <div class="logo-icon">🧞</div>
136
- <div class="logo-text">
137
- <h1>DebugGenie</h1>
138
- <p>Enterprise Error Analysis</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  </div>
140
  </div>
141
- """)
142
 
143
- def create_main_interface():
144
- """Create the main interface with Streamlined Flow layout."""
145
-
146
- with gr.Blocks(
147
- theme=debuggenie_theme,
148
- title="DebugGenie Flow",
149
- css=STREAMLINED_CSS
150
- ) as demo:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
151
 
152
- create_header()
 
 
 
 
 
 
 
 
 
 
 
 
153
 
154
- # Configuration Check
155
- if not MODAL_API_URL:
156
- with gr.Row():
157
- with gr.Column(elem_classes=["pro-card", "flow-section"]):
158
- gr.Markdown("### ⚠️ Configuration Required")
159
- gr.Markdown("Please configure `MODAL_API_URL` in Space settings.")
160
- else:
161
-
162
- # SECTION 1: THE ASK (Input)
163
- with gr.Column(elem_classes=["flow-section"]):
164
- gr.Markdown("### <span class='step-number'>1</span> Describe the Problem")
165
-
166
- error_input = gr.Textbox(
167
- label="Error Trace",
168
- placeholder="Paste your stack trace, error message, or describe the bug...",
169
- lines=6,
170
- max_lines=15,
171
- elem_classes=["input-area"],
172
- show_label=False
173
- )
174
-
175
- with gr.Accordion("Add Context (Screenshot / Files)", open=False):
176
- with gr.Row():
177
- screenshot_input = gr.Image(label="Screenshot", type="pil", height=150)
178
- files_input = gr.File(label="Source Files", file_count="multiple", height=100)
179
-
180
- analyze_btn = gr.Button(
181
- "Start Analysis",
182
- variant="primary",
183
- size="lg"
184
- )
185
 
186
- # SECTION 2: THE THINKING (Agent Activity)
187
- # Initially hidden, revealed on click
188
- with gr.Column(visible=False, elem_classes=["flow-section"]) as analysis_section:
189
- gr.Markdown("### <span class='step-number'>2</span> Agent Analysis")
190
-
191
- with gr.Group(elem_classes=["pro-card"]):
192
- agent_status = gr.Chatbot(
193
- label="Agent Activity",
194
- type="messages",
195
- height=250,
196
- show_label=False,
197
- bubble_full_width=False,
198
- avatar_images=(None, "https://api.iconify.design/fluent-emoji:robot.svg")
 
 
 
 
 
 
 
 
 
199
  )
200
- status_bar = gr.Markdown("**Status:** Initializing...", elem_id="status-bar")
 
 
 
201
 
202
- # SECTION 3: THE ANSWER (Solutions)
203
- # Initially hidden, revealed on completion
204
- with gr.Column(visible=False, elem_classes=["flow-section"]) as results_section:
205
- gr.Markdown("### <span class='step-number'>3</span> Recommended Solutions")
206
-
207
- root_cause_box = gr.Markdown(elem_classes=["pro-card"])
208
-
209
- gr.Markdown("#### Actionable Fixes", style="margin-top: 20px;")
210
- with gr.Row():
211
- solution_1 = gr.Markdown(elem_classes=["pro-card"])
212
- solution_2 = gr.Markdown(elem_classes=["pro-card"])
213
-
214
- with gr.Row(style="margin-top: 30px; border-top: 1px solid #27272a; padding-top: 20px;"):
215
- export_btn = gr.Button("πŸ“„ Export Report", size="sm", variant="secondary")
216
- voice_btn = gr.Button("πŸ”Š Listen to Briefing", size="sm", variant="secondary")
217
- audio_output = gr.Audio(visible=False, interactive=False)
218
-
219
- # Event Handlers
220
- def mock_analyze(error_text, screenshot, files, progress=gr.Progress()):
221
- import time
222
 
223
- # Reveal Analysis Section
224
- yield (
225
- gr.update(visible=True), # Show Analysis Section
226
- gr.update(visible=False), # Hide Results Section (reset)
227
- [], # Clear Chat
228
- "**Status:** Initializing...",
229
- gr.update(), gr.update(), gr.update()
230
  )
231
 
232
- messages = []
233
-
234
- # Step 1
235
- progress(0.2, desc="Initializing...")
236
- messages.append({"role": "assistant", "content": "πŸ”„ **System:** Initializing multi-agent swarm..."})
237
- yield (gr.update(), gr.update(), messages, "**Status:** Initializing...", gr.update(), gr.update(), gr.update())
238
- time.sleep(0.8)
239
-
240
- # Step 2
241
- progress(0.5, desc="Analyzing...")
242
- messages.append({"role": "assistant", "content": "πŸ€– **Claude:** Analyzing stack trace structure..."})
243
- messages.append({"role": "assistant", "content": "🧠 **Gemini:** Checking documentation..."})
244
- yield (gr.update(), gr.update(), messages, "**Status:** Analyzing...", gr.update(), gr.update(), gr.update())
245
- time.sleep(1.0)
246
-
247
- # Step 3
248
- progress(0.8, desc="Synthesizing...")
249
- messages.append({"role": "assistant", "content": "πŸ’‘ **GPT-4:** Synthesizing optimal solutions..."})
250
- yield (gr.update(), gr.update(), messages, "**Status:** Synthesizing...", gr.update(), gr.update(), gr.update())
251
- time.sleep(0.8)
252
-
253
- # Results
254
- root_cause = """
255
- ### 🎯 Root Cause Identified
256
- **Missing Dependency: `gradio`**
257
-
258
- The error `ModuleNotFoundError: No module named 'gradio'` indicates that the `gradio` package is not installed in your current Python environment.
259
- """
260
-
261
- sol1 = """
262
- #### βœ… Solution 1: Install Package
263
-
264
- Run the following command:
265
- ```bash
266
- pip install gradio
267
- ```
268
- <span class="badge badge-success">High Confidence</span>
269
- """
270
-
271
- sol2 = """
272
- #### πŸ”„ Solution 2: Check Environment
273
-
274
- Ensure you are in the correct virtualenv:
275
- ```bash
276
- source venv/bin/activate
277
- ```
278
- <span class="badge badge-warning">Medium Confidence</span>
279
- """
280
-
281
- messages.append({"role": "assistant", "content": "βœ… **System:** Analysis complete."})
282
-
283
- # Reveal Results Section
284
- yield (
285
- gr.update(),
286
- gr.update(visible=True), # Show Results
287
- messages,
288
- "**Status:** Complete",
289
- root_cause,
290
- sol1,
291
- sol2
292
- )
293
 
294
- analyze_btn.click(
295
- fn=mock_analyze,
296
- inputs=[error_input, screenshot_input, files_input],
297
- outputs=[
298
- analysis_section,
299
- results_section,
300
- agent_status,
301
- status_bar,
302
- root_cause_box,
303
- solution_1,
304
- solution_2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
305
  ]
306
- )
 
 
 
 
 
 
307
 
308
  return demo
309
 
310
  if __name__ == "__main__":
311
- demo = create_main_interface()
312
- demo.launch(
313
- server_name="0.0.0.0",
314
- server_port=7860,
315
- share=False
316
- )
 
1
  """
2
+ DebugGenie - Hackathon Edition πŸ†
3
+ Modern, Multi-Agent AI Debugging Assistant
4
  """
5
  import os
6
+ import time
7
  import gradio as gr
8
+ import plotly.graph_objects as go
9
+ import networkx as nx
10
 
11
+ # --- CONFIGURATION ---
12
  MODAL_API_URL = os.environ.get("MODAL_API_URL")
13
 
14
+ # --- CUSTOM CSS ---
15
+ HACKATHON_CSS = """
16
+ /* 🎨 Global Styles */
17
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;800&family=JetBrains+Mono:wght@400;700&display=swap');
18
+
19
  body {
20
+ font-family: 'Inter', sans-serif;
21
+ background-color: #f9fafb;
22
  }
23
 
24
+ .dark body {
25
+ background-color: #0f172a;
 
 
 
26
  }
27
 
28
+ .gradio-container {
29
+ max-width: 1400px !important;
30
  }
31
 
32
+ /* 🦸 Hero Section */
33
+ .hero-section {
34
+ background: linear-gradient(135deg, #1e40af 0%, #7c3aed 100%);
35
+ padding: 3rem 2rem;
36
+ border-radius: 1rem;
37
+ color: white;
38
+ text-align: center;
39
+ margin-bottom: 2rem;
40
+ box-shadow: 0 10px 25px rgba(30, 64, 175, 0.2);
41
+ position: relative;
42
+ overflow: hidden;
43
  }
44
 
45
+ .hero-title {
46
+ font-size: 3.5rem;
47
+ font-weight: 800;
48
+ margin-bottom: 0.5rem;
49
+ background: linear-gradient(to right, #ffffff, #e0e7ff);
50
+ -webkit-background-clip: text;
51
+ -webkit-text-fill-color: transparent;
52
+ text-shadow: 0 2px 10px rgba(0,0,0,0.1);
53
  }
54
 
55
+ .hero-subtitle {
56
+ font-size: 1.25rem;
57
+ color: #e0e7ff;
58
+ margin-bottom: 2rem;
59
+ font-weight: 500;
 
 
60
  }
61
 
62
+ .feature-badges {
63
+ display: flex;
64
+ justify-content: center;
65
+ gap: 1rem;
66
+ flex-wrap: wrap;
67
  }
68
 
69
+ .badge {
70
+ background: rgba(255, 255, 255, 0.15);
71
+ backdrop-filter: blur(10px);
72
+ padding: 0.5rem 1rem;
73
+ border-radius: 2rem;
74
+ font-size: 0.9rem;
75
+ font-weight: 600;
76
+ border: 1px solid rgba(255, 255, 255, 0.2);
77
+ transition: transform 0.2s;
78
  }
79
 
80
+ .badge:hover {
81
+ transform: translateY(-2px);
82
+ background: rgba(255, 255, 255, 0.25);
 
 
 
 
 
 
 
 
 
83
  }
84
 
85
+ /* πŸ“Š Stats Bar */
86
+ .stats-container {
87
+ display: flex;
88
+ justify-content: center;
89
+ gap: 3rem;
90
+ margin-bottom: 2rem;
91
+ padding: 1rem;
92
+ background: white;
93
+ border-radius: 0.75rem;
94
+ border: 1px solid #e5e7eb;
95
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05);
96
+ }
97
+
98
+ .dark .stats-container {
99
+ background: #1e293b;
100
+ border-color: #334155;
101
+ }
102
+
103
+ .stat-item {
104
+ display: flex;
105
  align-items: center;
106
+ gap: 0.5rem;
 
 
107
  font-weight: 600;
108
+ color: #4b5563;
109
+ }
110
+
111
+ .dark .stat-item {
112
+ color: #cbd5e1;
113
+ }
114
+
115
+ /* πŸ€– Agent Activity Monitor */
116
+ .agent-card {
117
+ background: white;
118
+ border: 1px solid #e5e7eb;
119
+ border-radius: 0.75rem;
120
+ padding: 1rem;
121
+ margin-bottom: 0.75rem;
122
+ transition: all 0.3s ease;
123
+ display: flex;
124
+ align-items: center;
125
+ gap: 1rem;
126
  }
127
 
128
+ .dark .agent-card {
129
+ background: #1e293b;
130
+ border-color: #334155;
 
131
  }
132
 
133
+ .agent-card:hover {
134
+ transform: translateX(4px);
135
+ border-color: #6366f1;
136
+ box-shadow: 0 4px 12px rgba(99, 102, 241, 0.1);
137
  }
138
 
139
+ .agent-avatar {
140
+ width: 40px;
141
+ height: 40px;
142
+ border-radius: 50%;
143
  display: flex;
144
  align-items: center;
145
  justify-content: center;
146
+ font-size: 1.25rem;
147
+ background: #f3f4f6;
148
+ }
149
+
150
+ .dark .agent-avatar {
151
+ background: #334155;
152
+ }
153
+
154
+ .agent-info {
155
+ flex: 1;
156
+ }
157
+
158
+ .agent-name {
159
+ font-weight: 700;
160
+ font-size: 0.9rem;
161
+ color: #1f2937;
162
+ margin-bottom: 0.25rem;
163
+ }
164
+
165
+ .dark .agent-name {
166
+ color: #f3f4f6;
167
+ }
168
+
169
+ .agent-status {
170
+ font-size: 0.8rem;
171
+ color: #6b7280;
172
+ }
173
+
174
+ .dark .agent-status {
175
+ color: #9ca3af;
176
  }
177
 
178
+ /* 🟒 Status Indicators */
179
+ .status-dot {
180
+ width: 10px;
181
+ height: 10px;
182
+ border-radius: 50%;
183
+ display: inline-block;
184
+ }
185
+
186
+ .status-dot.waiting { background-color: #ef4444; box-shadow: 0 0 0 2px rgba(239, 68, 68, 0.2); }
187
+ .status-dot.processing { background-color: #f59e0b; animation: pulse 1.5s infinite; }
188
+ .status-dot.complete { background-color: #10b981; }
189
+
190
+ @keyframes pulse {
191
+ 0% { box-shadow: 0 0 0 0 rgba(245, 158, 11, 0.4); }
192
+ 70% { box-shadow: 0 0 0 6px rgba(245, 158, 11, 0); }
193
+ 100% { box-shadow: 0 0 0 0 rgba(245, 158, 11, 0); }
194
+ }
195
+
196
+ /* πŸ’‘ Solution Cards */
197
+ .solution-card {
198
+ background: white;
199
+ border: 1px solid #e5e7eb;
200
+ border-left: 4px solid #10b981;
201
+ border-radius: 0.75rem;
202
+ padding: 1.5rem;
203
+ margin-bottom: 1.5rem;
204
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05);
205
+ }
206
+
207
+ .dark .solution-card {
208
+ background: #1e293b;
209
+ border-color: #334155;
210
+ border-left-color: #10b981;
211
+ }
212
+
213
+ .rank-badge {
214
+ background: linear-gradient(135deg, #10b981 0%, #059669 100%);
215
+ color: white;
216
+ padding: 0.25rem 0.75rem;
217
+ border-radius: 1rem;
218
+ font-size: 0.75rem;
219
+ font-weight: 700;
220
+ text-transform: uppercase;
221
+ display: inline-block;
222
+ margin-bottom: 0.75rem;
223
  }
224
 
225
+ .confidence-bar-bg {
226
+ height: 6px;
227
+ background: #e5e7eb;
228
+ border-radius: 3px;
229
+ margin-top: 0.5rem;
230
+ overflow: hidden;
231
  }
232
 
233
+ .dark .confidence-bar-bg {
234
+ background: #334155;
235
+ }
236
+
237
+ .confidence-bar-fill {
238
+ height: 100%;
239
+ background: linear-gradient(90deg, #10b981 0%, #3b82f6 100%);
240
+ border-radius: 3px;
241
+ transition: width 1s ease-out;
242
+ }
243
+
244
+ /* πŸ“± Mobile Tweaks */
245
+ @media (max-width: 768px) {
246
+ .hero-title { font-size: 2rem; }
247
+ .stats-container { flex-direction: column; gap: 1rem; }
248
  }
249
  """
250
 
251
+ # --- HELPER FUNCTIONS ---
252
+
253
+ def generate_agent_html(agent_name, status, message, progress):
254
+ """Generates HTML for a single agent card."""
255
+
256
+ status_class = "waiting"
257
+ if status == "processing": status_class = "processing"
258
+ elif status == "complete": status_class = "complete"
259
+
260
+ icon = "πŸ€–"
261
+ if "Claude" in agent_name: icon = "🧠"
262
+ elif "Gemini" in agent_name: icon = "✨"
263
+ elif "GPT-4" in agent_name: icon = "⚑"
264
+
265
+ return f"""
266
+ <div class="agent-card">
267
+ <div class="agent-avatar">{icon}</div>
268
+ <div class="agent-info">
269
+ <div class="agent-name">
270
+ {agent_name}
271
+ <span class="status-dot {status_class}" style="float: right;"></span>
272
+ </div>
273
+ <div class="agent-status">{message}</div>
274
+ <div class="confidence-bar-bg">
275
+ <div class="confidence-bar-fill" style="width: {progress}%;"></div>
276
+ </div>
277
  </div>
278
  </div>
279
+ """
280
 
281
+ def create_3d_viz():
282
+ """Creates a 3D network graph using Plotly."""
283
+ G = nx.random_geometric_graph(20, 0.125)
284
+ edge_x = []
285
+ edge_y = []
286
+ edge_z = []
287
+ for edge in G.edges():
288
+ x0, y0 = G.nodes[edge[0]]['pos']
289
+ x1, y1 = G.nodes[edge[1]]['pos']
290
+ edge_x.append(x0)
291
+ edge_y.append(y0)
292
+ edge_z.append(0) # Flat for now, but 3D capable
293
+ edge_x.append(x1)
294
+ edge_y.append(y1)
295
+ edge_z.append(0)
296
+ edge_x.append(None)
297
+ edge_y.append(None)
298
+ edge_z.append(None)
299
+
300
+ edge_trace = go.Scatter3d(
301
+ x=edge_x, y=edge_y, z=edge_z,
302
+ line=dict(width=0.5, color='#888'),
303
+ hoverinfo='none',
304
+ mode='lines')
305
+
306
+ node_x = []
307
+ node_y = []
308
+ node_z = []
309
+ for node in G.nodes():
310
+ x, y = G.nodes[node]['pos']
311
+ node_x.append(x)
312
+ node_y.append(y)
313
+ node_z.append(0)
314
+
315
+ node_trace = go.Scatter3d(
316
+ x=node_x, y=node_y, z=node_z,
317
+ mode='markers',
318
+ hoverinfo='text',
319
+ marker=dict(
320
+ showscale=True,
321
+ colorscale='YlGnBu',
322
+ reversescale=True,
323
+ color=[],
324
+ size=10,
325
+ colorbar=dict(
326
+ thickness=15,
327
+ title='Node Connections',
328
+ xanchor='left',
329
+ titleside='right'
330
+ ),
331
+ line_width=2))
332
+
333
+ fig = go.Figure(data=[edge_trace, node_trace],
334
+ layout=go.Layout(
335
+ title='Error Dependency Graph',
336
+ titlefont_size=16,
337
+ showlegend=False,
338
+ hovermode='closest',
339
+ margin=dict(b=20,l=5,r=5,t=40),
340
+ scene=dict(
341
+ xaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
342
+ yaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
343
+ zaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
344
+ )
345
+ ))
346
+ return fig
347
+
348
+ # --- MAIN APP ---
349
+
350
+ def create_app():
351
+ with gr.Blocks(css=HACKATHON_CSS, theme=gr.themes.Soft(primary_hue="indigo", neutral_hue="slate")) as demo:
352
 
353
+ # 1. HERO SECTION
354
+ with gr.Row(elem_classes="hero-section"):
355
+ gr.HTML("""
356
+ <div class="hero-content">
357
+ <h1 class="hero-title">DebugGenie 🧞</h1>
358
+ <p class="hero-subtitle">Multi-Agent AI Debugging Assistant</p>
359
+ <div class="feature-badges">
360
+ <span class="badge">πŸ€– Powered by Claude β€’ Gemini β€’ GPT-4</span>
361
+ <span class="badge">🎨 3D Visualization</span>
362
+ <span class="badge">πŸ”Š Voice Explanations</span>
363
+ </div>
364
+ </div>
365
+ """)
366
 
367
+ # 2. STATS BAR
368
+ with gr.Row(elem_classes="stats-container"):
369
+ gr.HTML("""
370
+ <div class="stat-item">πŸ€– 3 AI Agents Active</div>
371
+ <div class="stat-item">πŸ”§ 5 MCP Tools Connected</div>
372
+ <div class="stat-item">⚑ Real-time Analysis Ready</div>
373
+ """)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
374
 
375
+ # 3. MAIN LAYOUT (Two Columns)
376
+ with gr.Row():
377
+
378
+ # LEFT COLUMN: INPUT (40%)
379
+ with gr.Column(scale=2):
380
+ with gr.Group():
381
+ gr.Markdown("### πŸ“ Describe the Issue")
382
+ error_input = gr.Code(
383
+ label="Error Trace / Code Snippet",
384
+ language="python",
385
+ lines=10,
386
+ elem_classes="input-code"
387
+ )
388
+
389
+ with gr.Accordion("πŸ“Έ Add Context (Optional)", open=False):
390
+ screenshot_input = gr.Image(label="Upload Screenshot", type="pil", height=200)
391
+
392
+ analyze_btn = gr.Button(
393
+ "πŸ” Analyze Error",
394
+ variant="primary",
395
+ size="lg",
396
+ elem_id="analyze-btn"
397
  )
398
+
399
+ with gr.Row():
400
+ gr.Button("🎲 Try Example", size="sm", variant="secondary")
401
+ gr.Button("πŸ—‘οΈ Clear", size="sm", variant="secondary")
402
 
403
+ # RIGHT COLUMN: RESULTS (60%)
404
+ with gr.Column(scale=3):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
405
 
406
+ # Agent Activity Monitor
407
+ gr.Markdown("### πŸ“‘ Agent Activity Monitor")
408
+ agent_monitor = gr.HTML(
409
+ value=generate_agent_html("System", "waiting", "Ready to analyze...", 0) +
410
+ generate_agent_html("Claude", "waiting", "Standby", 0) +
411
+ generate_agent_html("Gemini", "waiting", "Standby", 0)
 
412
  )
413
 
414
+ # Results Tabs
415
+ with gr.Tabs(visible=False) as results_tabs:
416
+
417
+ # Tab 1: Solutions
418
+ with gr.Tab("🎯 Solutions"):
419
+ solutions_display = gr.HTML()
420
+
421
+ # Tab 2: 3D Viz
422
+ with gr.Tab("🎨 3D Visualization"):
423
+ viz_plot = gr.Plot(label="Error Graph")
424
+
425
+ # Tab 3: Raw Logs
426
+ with gr.Tab("πŸ“œ Agent Logs"):
427
+ chatbot = gr.Chatbot(label="Conversation", height=400, type="messages")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
428
 
429
+ # Voice Player (Bottom)
430
+ with gr.Group(visible=False) as voice_player:
431
+ gr.Markdown("### πŸ”Š Audio Briefing")
432
+ audio_out = gr.Audio(interactive=False)
433
+
434
+ # --- LOGIC ---
435
+ def analyze_error(error_code, img):
436
+ # 1. Initial State
437
+ yield {
438
+ agent_monitor: generate_agent_html("System", "processing", "Initializing swarm...", 10) +
439
+ generate_agent_html("Claude", "waiting", "Queued", 0) +
440
+ generate_agent_html("Gemini", "waiting", "Queued", 0),
441
+ results_tabs: gr.update(visible=True),
442
+ voice_player: gr.update(visible=False)
443
+ }
444
+ time.sleep(1)
445
+
446
+ # 2. Claude Analysis
447
+ yield {
448
+ agent_monitor: generate_agent_html("System", "complete", "Swarm Active", 100) +
449
+ generate_agent_html("Claude", "processing", "Analyzing syntax tree...", 45) +
450
+ generate_agent_html("Gemini", "waiting", "Queued", 0)
451
+ }
452
+ time.sleep(1.5)
453
+
454
+ # 3. Gemini Analysis
455
+ yield {
456
+ agent_monitor: generate_agent_html("System", "complete", "Swarm Active", 100) +
457
+ generate_agent_html("Claude", "complete", "Analysis complete", 100) +
458
+ generate_agent_html("Gemini", "processing", "Checking documentation...", 60)
459
+ }
460
+ time.sleep(1.5)
461
+
462
+ # 4. Finalizing
463
+ yield {
464
+ agent_monitor: generate_agent_html("System", "complete", "Swarm Active", 100) +
465
+ generate_agent_html("Claude", "complete", "Analysis complete", 100) +
466
+ generate_agent_html("Gemini", "complete", "Solutions found", 100)
467
+ }
468
+
469
+ # 5. Show Results
470
+ solution_html = """
471
+ <div class="solution-card">
472
+ <div class="rank-badge">πŸ₯‡ Top Recommendation</div>
473
+ <h3>Install Missing Dependency</h3>
474
+ <p>The error <code>ModuleNotFoundError</code> indicates that <code>gradio</code> is not installed.</p>
475
+ <div class="confidence-bar-bg"><div class="confidence-bar-fill" style="width: 98%;"></div></div>
476
+ <pre style="background: #f3f4f6; padding: 10px; border-radius: 5px; margin-top: 10px;">pip install gradio</pre>
477
+ </div>
478
+
479
+ <div class="solution-card" style="border-left-color: #f59e0b;">
480
+ <div class="rank-badge" style="background: #f59e0b;">πŸ₯ˆ Alternative</div>
481
+ <h3>Check Virtual Environment</h3>
482
+ <p>Ensure you are running in the correct venv.</p>
483
+ <div class="confidence-bar-bg"><div class="confidence-bar-fill" style="width: 75%; background: #f59e0b;"></div></div>
484
+ </div>
485
+ """
486
+
487
+ fig = create_3d_viz()
488
+
489
+ yield {
490
+ solutions_display: solution_html,
491
+ viz_plot: fig,
492
+ voice_player: gr.update(visible=True),
493
+ chatbot: [
494
+ {"role": "user", "content": "Analyze this error."},
495
+ {"role": "assistant", "content": "I've analyzed the stack trace. The root cause is a missing library."}
496
  ]
497
+ }
498
+
499
+ analyze_btn.click(
500
+ analyze_error,
501
+ inputs=[error_input, screenshot_input],
502
+ outputs=[agent_monitor, results_tabs, voice_player, solutions_display, viz_plot, chatbot]
503
+ )
504
 
505
  return demo
506
 
507
  if __name__ == "__main__":
508
+ demo = create_app()
509
+ demo.launch(server_name="0.0.0.0", server_port=7860)