eduard76 commited on
Commit
a1a484a
·
verified ·
1 Parent(s): 8d36ad4

Create main.py

Browse files
Files changed (1) hide show
  1. main.py +607 -0
main.py ADDED
@@ -0,0 +1,607 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import asyncio
3
+ from textwrap import dedent
4
+ from dotenv import load_dotenv
5
+ from crewai import Agent, Crew, Process, Task
6
+ from langchain_openai import ChatOpenAI
7
+ import gradio as gr
8
+
9
+ # Load the .env file to get the API key
10
+ load_dotenv()
11
+
12
+ # Verify API key exists
13
+ if not os.getenv("OPENAI_API_KEY"):
14
+ raise ValueError("OPENAI_API_KEY not found in environment variables. Please add it to your .env file.")
15
+
16
+ # Initialize LLM
17
+ llm = ChatOpenAI(
18
+ model="gpt-4-turbo-preview",
19
+ temperature=0.1,
20
+ api_key=os.getenv("OPENAI_API_KEY")
21
+ )
22
+
23
+ # --- 1. Agent Definitions ---
24
+ lead_architect = Agent(
25
+ role="Lead Network Architect",
26
+ goal=dedent("""
27
+ Translate high-level business and application needs into a detailed list
28
+ of specific, actionable technical requirements for a new data center network.
29
+ """),
30
+ backstory=dedent("""
31
+ You are a seasoned Lead Architect who excels at interfacing with business stakeholders.
32
+ Your primary skill is listening to business goals and application needs, then distilling
33
+ them into a clear and comprehensive list of technical specifications that engineers can build from.
34
+ You think in terms of availability, security, scalability, and performance metrics.
35
+ """),
36
+ llm=llm,
37
+ allow_delegation=False,
38
+ verbose=True,
39
+ )
40
+
41
+ senior_network_architect = Agent(
42
+ role="Senior Network Architect",
43
+ goal=dedent("""
44
+ Take a detailed list of technical requirements and create three distinct, high-level
45
+ data center network designs. Each design must be for a different major vendor
46
+ (Cisco, Arista, Juniper) and must meet all specified technical requirements.
47
+ """),
48
+ backstory=dedent("""
49
+ You are a hands-on Senior Network Architect with deep product knowledge across
50
+ Cisco, Arista, and Juniper. You are an expert in creating detailed High-Level Designs (HLDs)
51
+ based on a given set of technical specifications. You focus purely on the technical implementation.
52
+ """),
53
+ llm=llm,
54
+ allow_delegation=False,
55
+ verbose=True,
56
+ )
57
+
58
+ peer_review_architect = Agent(
59
+ role="Peer Review Architect",
60
+ goal=dedent("""
61
+ Critically review three network designs against the original technical requirements
62
+ to validate their feasibility, compare their trade-offs, and select the optimal solution.
63
+ """),
64
+ backstory=dedent("""
65
+ You are an impartial and meticulous architect responsible for quality control.
66
+ Your job is to act as a peer reviewer. You take a set of designs and the original
67
+ requirements, and your task is to find any gaps, inconsistencies, or trade-offs.
68
+ You provide the final validation and reasoned recommendation on which design to proceed with.
69
+ """),
70
+ llm=llm,
71
+ allow_delegation=False,
72
+ verbose=True,
73
+ )
74
+
75
+ # --- 2. Task Definitions ---
76
+ def create_tasks(business_requirements, application_requirements):
77
+ """Create tasks with proper input context"""
78
+
79
+ initial_requirements = f"Business Requirements: {business_requirements}\nApplication Requirements: {application_requirements}"
80
+
81
+ technical_translation_task = Task(
82
+ description=dedent(f"""
83
+ Analyze the following business and application requirements and translate
84
+ them into a detailed list of technical network requirements.
85
+
86
+ Create a comprehensive table with three columns: 'Category', 'Requirement', and 'Justification'.
87
+
88
+ Categories should include: Availability, Performance, Security, Scalability, Management, and Budget.
89
+
90
+ Requirements to analyze:
91
+ {initial_requirements}
92
+
93
+ Focus on creating specific, measurable technical requirements that can guide network design decisions.
94
+ """),
95
+ expected_output="A detailed markdown table with three columns: 'Category', 'Requirement', and 'Justification'.",
96
+ agent=lead_architect,
97
+ )
98
+
99
+ design_creation_task = Task(
100
+ description=dedent("""
101
+ Based on the technical requirements from the Lead Architect, create three distinct
102
+ high-level data center designs using a spine-leaf architecture.
103
+
104
+ **CRITICAL:** Prioritize the original business requirements when making design trade-offs.
105
+ If 'Strict Budget' was selected, choose cost-effective hardware even if it means
106
+ compromising on supporting requirements.
107
+
108
+ Create one design for each vendor:
109
+ - Cisco design with specific switch models and NX-OS
110
+ - Juniper design with specific switch models and Junos
111
+ - Arista design with specific switch models and EOS
112
+
113
+ For each design, specify:
114
+ 1. Recommended spine switch models and quantities
115
+ 2. Recommended leaf switch models and quantities
116
+ 3. Network operating system version
117
+ 4. Brief rationale explaining how it meets the technical requirements
118
+ 5. Estimated cost range if budget was a consideration
119
+ """),
120
+ expected_output="Three complete high-level designs, one for each vendor (Cisco, Juniper, Arista).",
121
+ agent=senior_network_architect,
122
+ context=[technical_translation_task]
123
+ )
124
+
125
+ validation_task = Task(
126
+ description=dedent("""
127
+ Review the technical requirements and the three vendor designs (Cisco, Juniper, Arista)
128
+ provided by previous team members.
129
+
130
+ Create a comprehensive validation report with these sections:
131
+
132
+ 1. **Requirements Validation**: Check if each vendor design meets all technical requirements
133
+ 2. **Comparative Analysis**: Compare pros/cons of Cisco vs Juniper vs Arista solutions
134
+ 3. **Trade-off Analysis**: Identify any compromises made in each design
135
+ 4. **Final Recommendation**: Select the best vendor solution with clear justification
136
+ 5. **Implementation Considerations**: Next steps and potential risks
137
+
138
+ Base your analysis solely on the specific vendor designs provided, not generic concepts.
139
+ """),
140
+ expected_output="A comprehensive validation report with requirements check, vendor comparison, and final recommendation.",
141
+ agent=peer_review_architect,
142
+ context=[technical_translation_task, design_creation_task]
143
+ )
144
+
145
+ return [technical_translation_task, design_creation_task, validation_task]
146
+
147
+ # --- 3. CrewAI Execution Function ---
148
+ def run_design_crew(business_reqs_list, app_reqs_list, progress=gr.Progress()):
149
+ """Run the CrewAI design crew with proper execution flow"""
150
+
151
+ # Input validation
152
+ if not business_reqs_list and not app_reqs_list:
153
+ return (
154
+ "❌ **Error**: Please select at least one requirement.",
155
+ "",
156
+ ""
157
+ )
158
+
159
+ # Verify API key
160
+ if not os.getenv("OPENAI_API_KEY"):
161
+ return (
162
+ "❌ **Error**: OPENAI_API_KEY not found. Please add it to your .env file.",
163
+ "",
164
+ ""
165
+ )
166
+
167
+ try:
168
+ # Prepare requirements strings
169
+ business_reqs_str = ", ".join(business_reqs_list) if business_reqs_list else "None specified"
170
+ app_reqs_str = ", ".join(app_reqs_list) if app_reqs_list else "None specified"
171
+
172
+ progress(0.1, desc="Initializing AI agents...")
173
+
174
+ # Create tasks
175
+ tasks = create_tasks(business_reqs_str, app_reqs_str)
176
+
177
+ # Create crew
178
+ crew = Crew(
179
+ agents=[lead_architect, senior_network_architect, peer_review_architect],
180
+ tasks=tasks,
181
+ process=Process.sequential,
182
+ verbose=True,
183
+ memory=True, # Enable memory for better context retention
184
+ )
185
+
186
+ progress(0.2, desc="Starting design process...")
187
+
188
+ # Prepare inputs
189
+ inputs = {
190
+ 'business_requirements': business_reqs_str,
191
+ 'application_requirements': app_reqs_str,
192
+ 'requirements_context': f"Business: {business_reqs_str}\nApplications: {app_reqs_str}"
193
+ }
194
+
195
+ progress(0.3, desc="Lead Architect analyzing requirements...")
196
+
197
+ # Execute crew
198
+ result = crew.kickoff(inputs=inputs)
199
+
200
+ progress(0.9, desc="Finalizing reports...")
201
+
202
+ # Extract individual task outputs
203
+ task_outputs = result.tasks_output if hasattr(result, 'tasks_output') else []
204
+
205
+ if len(task_outputs) >= 3:
206
+ lead_output = task_outputs[0].raw if hasattr(task_outputs[0], 'raw') else str(task_outputs[0])
207
+ senior_output = task_outputs[1].raw if hasattr(task_outputs[1], 'raw') else str(task_outputs[1])
208
+ peer_output = task_outputs[2].raw if hasattr(task_outputs[2], 'raw') else str(task_outputs[2])
209
+ else:
210
+ # Fallback if task outputs aren't properly separated
211
+ full_output = str(result)
212
+ # Try to split the output into sections
213
+ sections = full_output.split("# Task")
214
+ if len(sections) >= 3:
215
+ lead_output = f"# Technical Requirements\n{sections[1]}" if len(sections) > 1 else "Output processing..."
216
+ senior_output = f"# Network Designs\n{sections[2]}" if len(sections) > 2 else "Processing designs..."
217
+ peer_output = f"# Validation Report\n{sections[3]}" if len(sections) > 3 else "Finalizing validation..."
218
+ else:
219
+ lead_output = "✅ Requirements analysis complete"
220
+ senior_output = "✅ Designs generated"
221
+ peer_output = full_output
222
+
223
+ progress(1.0, desc="Complete!")
224
+
225
+ return lead_output, senior_output, peer_output
226
+
227
+ except Exception as e:
228
+ error_msg = f"❌ **Error occurred**: {str(e)}\n\n**Troubleshooting:**\n- Check your OpenAI API key\n- Ensure stable internet connection\n- Try selecting fewer requirements if the request is too complex"
229
+ return error_msg, error_msg, error_msg
230
+
231
+ # --- 4. Enhanced CSS ---
232
+ custom_css = """
233
+ <style>
234
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
235
+
236
+ /* Hide Gradio footer */
237
+ footer { display: none !important; }
238
+
239
+ /* Main container styling */
240
+ .gradio-container {
241
+ max-width: 1200px !important;
242
+ margin: 0 auto !important;
243
+ padding: 2rem !important;
244
+ background: #ffffff !important;
245
+ font-family: 'Inter', system-ui, -apple-system, sans-serif !important;
246
+ min-height: 100vh !important;
247
+ }
248
+
249
+ /* Clean container backgrounds */
250
+ .gradio-blocks, .gradio-blocks > div, .gradio-group, .gradio-column, .gradio-row {
251
+ background: transparent !important;
252
+ border: none !important;
253
+ box-shadow: none !important;
254
+ }
255
+
256
+ /* Header styling */
257
+ .main-header {
258
+ text-align: left !important;
259
+ margin-bottom: 3rem !important;
260
+ background: transparent !important;
261
+ }
262
+
263
+ .header-title {
264
+ display: flex !important;
265
+ align-items: center !important;
266
+ gap: 0.75rem !important;
267
+ font-size: 1.75rem !important;
268
+ font-weight: 600 !important;
269
+ color: #1f2937 !important;
270
+ margin-bottom: 1rem !important;
271
+ font-family: 'Inter', sans-serif !important;
272
+ }
273
+
274
+ .bot-icon {
275
+ width: 1.75rem !important;
276
+ height: 1.75rem !important;
277
+ color: #3b82f6 !important;
278
+ }
279
+
280
+ .header-subtitle {
281
+ color: #6b7280 !important;
282
+ font-size: 1rem !important;
283
+ margin: 0 !important;
284
+ font-weight: 400 !important;
285
+ font-family: 'Inter', sans-serif !important;
286
+ line-height: 1.5 !important;
287
+ }
288
+
289
+ /* Section headers */
290
+ .section-title {
291
+ color: #3b82f6 !important;
292
+ font-size: 1.125rem !important;
293
+ font-weight: 700 !important;
294
+ margin-bottom: 1.5rem !important;
295
+ margin-top: 2rem !important;
296
+ padding: 0 0 0.5rem 0 !important;
297
+ background: transparent !important;
298
+ font-family: 'Inter', sans-serif !important;
299
+ border-bottom: 2px solid #e5e7eb !important;
300
+ }
301
+
302
+ .section-title:first-of-type {
303
+ margin-top: 0 !important;
304
+ }
305
+
306
+ /* Checkbox styling */
307
+ .gradio-checkboxgroup {
308
+ gap: 0.5rem !important;
309
+ background: transparent !important;
310
+ border: none !important;
311
+ padding: 0 !important;
312
+ margin-bottom: 2rem !important;
313
+ }
314
+
315
+ .gradio-checkboxgroup label {
316
+ background: #f8fafc !important;
317
+ border: 1px solid #e2e8f0 !important;
318
+ border-radius: 0.5rem !important;
319
+ padding: 0.75rem 1rem !important;
320
+ margin: 0 0 0.5rem 0 !important;
321
+ transition: all 0.2s ease !important;
322
+ cursor: pointer !important;
323
+ display: flex !important;
324
+ align-items: center !important;
325
+ gap: 0.75rem !important;
326
+ font-size: 0.9rem !important;
327
+ line-height: 1.4 !important;
328
+ color: #475569 !important;
329
+ font-weight: 400 !important;
330
+ font-family: 'Inter', sans-serif !important;
331
+ }
332
+
333
+ .gradio-checkboxgroup label:hover {
334
+ background: #f1f5f9 !important;
335
+ border-color: #10b981 !important;
336
+ color: #1e293b !important;
337
+ }
338
+
339
+ .gradio-checkboxgroup input[type="checkbox"] {
340
+ accent-color: #10b981 !important;
341
+ width: 1rem !important;
342
+ height: 1rem !important;
343
+ margin: 0 !important;
344
+ flex-shrink: 0 !important;
345
+ border-radius: 0.25rem !important;
346
+ }
347
+
348
+ .gradio-checkboxgroup label:has(input[type="checkbox"]:checked) {
349
+ background: #ecfdf5 !important;
350
+ border-color: #10b981 !important;
351
+ color: #065f46 !important;
352
+ font-weight: 500 !important;
353
+ }
354
+
355
+ /* Generate button */
356
+ .generate-btn {
357
+ background: linear-gradient(135deg, #10b981 0%, #059669 100%) !important;
358
+ color: white !important;
359
+ border: none !important;
360
+ padding: 1rem 1.5rem !important;
361
+ border-radius: 0.75rem !important;
362
+ font-weight: 600 !important;
363
+ font-size: 1rem !important;
364
+ width: 100% !important;
365
+ margin-top: 2rem !important;
366
+ cursor: pointer !important;
367
+ transition: all 0.3s ease !important;
368
+ font-family: 'Inter', sans-serif !important;
369
+ min-height: 3rem !important;
370
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1) !important;
371
+ }
372
+
373
+ .generate-btn:hover {
374
+ background: linear-gradient(135deg, #059669 0%, #047857 100%) !important;
375
+ transform: translateY(-2px) !important;
376
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1) !important;
377
+ }
378
+
379
+ /* Report section titles */
380
+ .report-title {
381
+ color: #1f2937 !important;
382
+ font-size: 1.125rem !important;
383
+ font-weight: 600 !important;
384
+ margin-bottom: 1rem !important;
385
+ margin-top: 2rem !important;
386
+ background: transparent !important;
387
+ font-family: 'Inter', sans-serif !important;
388
+ padding: 0.5rem 0 !important;
389
+ border-bottom: 1px solid #e5e7eb !important;
390
+ }
391
+
392
+ .report-title:first-of-type {
393
+ margin-top: 0 !important;
394
+ }
395
+
396
+ /* Markdown output */
397
+ .gradio-markdown {
398
+ background: transparent !important;
399
+ border: none !important;
400
+ padding: 1rem !important;
401
+ font-family: 'Inter', sans-serif !important;
402
+ line-height: 1.6 !important;
403
+ background: #fafafa !important;
404
+ border-radius: 0.5rem !important;
405
+ border: 1px solid #e5e7eb !important;
406
+ }
407
+
408
+ .gradio-markdown h1, .gradio-markdown h2, .gradio-markdown h3 {
409
+ color: #1f2937 !important;
410
+ font-weight: 600 !important;
411
+ margin-top: 1.5rem !important;
412
+ margin-bottom: 0.5rem !important;
413
+ }
414
+
415
+ .gradio-markdown table {
416
+ width: 100% !important;
417
+ border-collapse: collapse !important;
418
+ margin: 1rem 0 !important;
419
+ background: white !important;
420
+ border-radius: 0.5rem !important;
421
+ overflow: hidden !important;
422
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1) !important;
423
+ }
424
+
425
+ .gradio-markdown table th,
426
+ .gradio-markdown table td {
427
+ padding: 0.75rem !important;
428
+ border: 1px solid #e5e7eb !important;
429
+ text-align: left !important;
430
+ vertical-align: top !important;
431
+ }
432
+
433
+ .gradio-markdown table th {
434
+ background: #f8fafc !important;
435
+ font-weight: 600 !important;
436
+ color: #374151 !important;
437
+ }
438
+
439
+ .gradio-markdown table tr:nth-child(even) {
440
+ background: #f9fafb !important;
441
+ }
442
+
443
+ /* Placeholder content */
444
+ .placeholder-content {
445
+ text-align: center !important;
446
+ color: #9ca3af !important;
447
+ padding: 4rem 2rem !important;
448
+ background: #f8fafc !important;
449
+ border: 2px dashed #e5e7eb !important;
450
+ border-radius: 0.75rem !important;
451
+ font-family: 'Inter', sans-serif !important;
452
+ }
453
+
454
+ .placeholder-icon {
455
+ width: 3rem !important;
456
+ height: 3rem !important;
457
+ margin: 0 auto 1rem auto !important;
458
+ opacity: 0.5 !important;
459
+ color: #9ca3af !important;
460
+ }
461
+
462
+ .placeholder-content p {
463
+ font-size: 0.9rem !important;
464
+ color: #6b7280 !important;
465
+ margin: 0 !important;
466
+ font-weight: 400 !important;
467
+ }
468
+
469
+ /* Layout */
470
+ .gradio-row {
471
+ gap: 3rem !important;
472
+ align-items: flex-start !important;
473
+ }
474
+
475
+ /* Progress styling */
476
+ .gradio-progress {
477
+ background: #f3f4f6 !important;
478
+ border-radius: 0.5rem !important;
479
+ overflow: hidden !important;
480
+ }
481
+
482
+ .gradio-progress .progress-bar {
483
+ background: linear-gradient(90deg, #10b981, #059669) !important;
484
+ transition: width 0.3s ease !important;
485
+ }
486
+ </style>
487
+ """
488
+
489
+ # --- 5. Gradio Interface ---
490
+ with gr.Blocks(
491
+ theme="soft",
492
+ css=custom_css,
493
+ title="AI Co-Designer for Data Center Networks"
494
+ ) as demo:
495
+
496
+ # Header
497
+ gr.HTML("""
498
+ <div class="main-header">
499
+ <div class="header-title">
500
+ <svg class="bot-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
501
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"/>
502
+ </svg>
503
+ AI Co-Designer for Data Center Networks
504
+ </div>
505
+ <p class="header-subtitle">
506
+ Select your business and application requirements to generate comprehensive network designs with AI-powered validation.
507
+ </p>
508
+ </div>
509
+ """)
510
+
511
+ # Main layout
512
+ with gr.Row():
513
+ # Left column - Requirements
514
+ with gr.Column(scale=1):
515
+ # Business Requirements
516
+ gr.HTML('<div class="section-title">Business Requirements</div>')
517
+ business_checkboxes = gr.CheckboxGroup(
518
+ choices=[
519
+ "Strict Budget (CAPEX)",
520
+ "High Scalability",
521
+ "High Automation (OPEX)",
522
+ "High Availability",
523
+ "Regulatory Compliance"
524
+ ],
525
+ value=[],
526
+ container=False,
527
+ show_label=False
528
+ )
529
+
530
+ # Application Requirements
531
+ gr.HTML('<div class="section-title">Application Requirements</div>')
532
+ application_checkboxes = gr.CheckboxGroup(
533
+ choices=[
534
+ "Large-Scale Virtualization",
535
+ "AI/ML Workloads",
536
+ "Low-Latency / Real-time",
537
+ "Big Data Clusters",
538
+ "High East-West Traffic"
539
+ ],
540
+ value=[],
541
+ container=False,
542
+ show_label=False
543
+ )
544
+
545
+ # Generate Button
546
+ submit_button = gr.Button(
547
+ "🚀 Generate & Validate Design",
548
+ elem_classes=["generate-btn"]
549
+ )
550
+
551
+ # Right column - Agent outputs
552
+ with gr.Column(scale=2):
553
+ # Lead Architect Output
554
+ gr.HTML('<div class="report-title">💡 Lead Architect: Technical Requirements</div>')
555
+ lead_architect_output = gr.Markdown(
556
+ value="""<div class="placeholder-content">
557
+ <svg class="placeholder-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
558
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
559
+ </svg>
560
+ <p>Requirements analysis will appear here...</p>
561
+ </div>""",
562
+ container=False,
563
+ show_label=False
564
+ )
565
+
566
+ # Senior Architect Output
567
+ gr.HTML('<div class="report-title">🏗️ Senior Architect: Network Designs</div>')
568
+ senior_architect_output = gr.Markdown(
569
+ value="""<div class="placeholder-content">
570
+ <svg class="placeholder-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
571
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4"/>
572
+ </svg>
573
+ <p>Network designs will appear here...</p>
574
+ </div>""",
575
+ container=False,
576
+ show_label=False
577
+ )
578
+
579
+ # Peer Review Output
580
+ gr.HTML('<div class="report-title">✅ Peer Review: Validation & Recommendation</div>')
581
+ peer_review_output = gr.Markdown(
582
+ value="""<div class="placeholder-content">
583
+ <svg class="placeholder-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
584
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
585
+ </svg>
586
+ <p>Validation report will appear here...</p>
587
+ </div>""",
588
+ container=False,
589
+ show_label=False
590
+ )
591
+
592
+ # Connect the functionality
593
+ submit_button.click(
594
+ fn=run_design_crew,
595
+ inputs=[business_checkboxes, application_checkboxes],
596
+ outputs=[lead_architect_output, senior_architect_output, peer_review_output],
597
+ show_progress=True
598
+ )
599
+
600
+ # Launch the app
601
+ if __name__ == "__main__":
602
+ demo.launch(
603
+ share=True,
604
+ server_name="0.0.0.0",
605
+ server_port=7860,
606
+ show_error=True
607
+ )