Spaces:
Sleeping
Sleeping
Graham Paasch commited on
Commit ·
ebd3edc
1
Parent(s): f7a97bc
Streamline UI to focus on automation pipeline
Browse files- Removed old tabs: Plan, Risk & Topology, Diffs, Rollback, OOB Troubleshooting, Synapse Log
- Pipeline is now the main interface (left: input, right: outputs)
- Tool Calls log moved to left column for visibility
- Advanced Operations (Build Network, Lab Management) collapsed in accordion
- Clean, focused UX: consultation → SoT → diagram → BOM → setup → deploy → observability → validation
- Removed unused event handlers and functions
app.py
CHANGED
|
@@ -205,103 +205,58 @@ def build_ui():
|
|
| 205 |
|
| 206 |
device_choices = topology.list_devices()
|
| 207 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 208 |
with gr.Row(elem_classes=["og-main-row"]):
|
| 209 |
with gr.Column(scale=1, elem_classes=["og-panel"]):
|
| 210 |
-
|
| 211 |
-
label="Describe
|
| 212 |
placeholder=(
|
| 213 |
-
"Example:
|
| 214 |
-
"
|
|
|
|
|
|
|
| 215 |
),
|
| 216 |
-
lines=
|
| 217 |
)
|
| 218 |
-
|
|
|
|
|
|
|
|
|
|
| 219 |
|
| 220 |
with gr.Column(scale=2, elem_classes=["og-panel", "og-tabs"]):
|
| 221 |
-
|
| 222 |
-
|
| 223 |
-
|
| 224 |
-
with gr.Tab("Risk & Topology"):
|
| 225 |
-
risk_md = gr.Markdown(label="Risk & Topology Summary")
|
| 226 |
-
|
| 227 |
-
with gr.Tab("Diffs"):
|
| 228 |
-
diffs_md = gr.Markdown(label="Config Diff Summary")
|
| 229 |
-
|
| 230 |
-
with gr.Tab("Rollback"):
|
| 231 |
-
rollback_md = gr.Markdown(label="Rollback Plan")
|
| 232 |
-
|
| 233 |
-
with gr.Tab("Tool Calls"):
|
| 234 |
-
tool_log_md = gr.Markdown(label="MCP Tool Call Log")
|
| 235 |
-
|
| 236 |
-
with gr.Tab("OOB Troubleshooting"):
|
| 237 |
-
troubleshoot_device = gr.Dropdown(
|
| 238 |
-
label="Device",
|
| 239 |
-
choices=device_choices or ["leaf-01", "leaf-02"],
|
| 240 |
-
value=device_choices[0] if device_choices else "leaf-01",
|
| 241 |
-
)
|
| 242 |
-
troubleshoot_text = gr.Textbox(
|
| 243 |
-
label="Describe the issue",
|
| 244 |
-
placeholder="Example: Link flaps on leaf-01, seeing packet loss.",
|
| 245 |
-
lines=3,
|
| 246 |
-
)
|
| 247 |
-
troubleshoot_btn = gr.Button("Run Troubleshooting")
|
| 248 |
-
troubleshoot_md = gr.Markdown(label="Troubleshooting Summary")
|
| 249 |
-
troubleshoot_log = gr.Markdown(label="Troubleshooting Log")
|
| 250 |
-
troubleshoot_actions = gr.Markdown(label="Recommended Actions")
|
| 251 |
-
troubleshoot_conf = gr.Markdown(label="Root Cause Confidence")
|
| 252 |
-
troubleshoot_state = gr.Markdown(label="Device State Snapshot")
|
| 253 |
-
execute_btn = gr.Button("Execute Recovery Plan")
|
| 254 |
-
execute_summary = gr.Markdown(label="Recovery Execution Summary")
|
| 255 |
-
execute_log = gr.Markdown(label="Recovery Execution Log")
|
| 256 |
-
reset_btn = gr.Button("Reset Overgrowth State (dangerous)", variant="secondary")
|
| 257 |
-
reset_md = gr.Markdown(label="State Reset Log")
|
| 258 |
-
|
| 259 |
-
with gr.Tab("Synapse Log"):
|
| 260 |
-
synapse_btn = gr.Button("Refresh Log")
|
| 261 |
-
synapse_md = gr.Markdown(label="Overgrowth Synapse Log")
|
| 262 |
|
| 263 |
-
with gr.
|
| 264 |
-
gr.
|
| 265 |
-
|
| 266 |
|
| 267 |
-
|
| 268 |
-
|
| 269 |
-
2. 📋 Source of Truth - Generate data model
|
| 270 |
-
3. 📊 Diagram - Visualize the design
|
| 271 |
-
4. 🛒 Bill of Materials - Shopping list
|
| 272 |
-
5. 🔧 Setup Guide - Human deployment steps + OOB network
|
| 273 |
-
6. 🤖 Autonomous Deploy - AI configures everything
|
| 274 |
-
7. 👁️ Observability - Monitoring & topology discovery
|
| 275 |
-
8. ✅ Validation - Verify intended state
|
| 276 |
-
""")
|
| 277 |
|
| 278 |
-
with gr.
|
| 279 |
-
|
| 280 |
-
|
| 281 |
-
|
| 282 |
-
|
| 283 |
-
|
| 284 |
-
|
| 285 |
-
|
| 286 |
-
|
| 287 |
-
gr.Markdown("#### Pipeline Progress")
|
| 288 |
-
pipeline_status = gr.Markdown(label="Status")
|
| 289 |
-
|
| 290 |
-
with gr.Column():
|
| 291 |
-
gr.Markdown("#### Generated Outputs")
|
| 292 |
-
with gr.Tabs():
|
| 293 |
-
with gr.Tab("📋 Source of Truth"):
|
| 294 |
-
sot_output = gr.Code(label="Network Model (YAML)", language="yaml")
|
| 295 |
-
|
| 296 |
-
with gr.Tab("🛒 Bill of Materials"):
|
| 297 |
-
bom_output = gr.Markdown(label="Shopping List")
|
| 298 |
-
|
| 299 |
-
with gr.Tab("🔧 Setup Guide"):
|
| 300 |
-
setup_output = gr.Markdown(label="Deployment Guide")
|
| 301 |
-
|
| 302 |
-
with gr.Tab("📊 Diagram"):
|
| 303 |
-
diagram_output = gr.Textbox(label="Network Diagram", lines=20, max_lines=40)
|
| 304 |
-
|
| 305 |
with gr.Tab("Build Network"):
|
| 306 |
gr.Markdown("### 🌱 Build Network from Description\nDescribe your network needs in plain English - Overgrowth builds and configures it automatically.")
|
| 307 |
|
|
@@ -395,21 +350,6 @@ def build_ui():
|
|
| 395 |
backup_btn = gr.Button("Backup Config", variant="secondary")
|
| 396 |
backup_result = gr.Markdown(label="Backup Result")
|
| 397 |
|
| 398 |
-
def on_run(change_text: str):
|
| 399 |
-
"""
|
| 400 |
-
Wraps the agent pipeline for Gradio.
|
| 401 |
-
Returns:
|
| 402 |
-
plan_markdown, risk_markdown, diffs_markdown,
|
| 403 |
-
rollback_markdown, tool_log_markdown
|
| 404 |
-
"""
|
| 405 |
-
return analyze_change(change_text)
|
| 406 |
-
|
| 407 |
-
def run_troubleshoot(dev, text):
|
| 408 |
-
return oob_troubleshoot(dev, text)
|
| 409 |
-
|
| 410 |
-
def execute_recovery_plan_wrapper(dev, text):
|
| 411 |
-
return perform_recovery(dev, text)
|
| 412 |
-
|
| 413 |
# Lab Management handlers
|
| 414 |
def refresh_projects():
|
| 415 |
projects = get_lab_projects()
|
|
@@ -582,38 +522,12 @@ def build_ui():
|
|
| 582 |
error_json = json.dumps(result, indent=2)
|
| 583 |
return error_msg, error_json
|
| 584 |
|
| 585 |
-
|
| 586 |
-
fn=on_run,
|
| 587 |
-
inputs=[change_request],
|
| 588 |
-
outputs=[plan_md, risk_md, diffs_md, rollback_md, tool_log_md],
|
| 589 |
-
)
|
| 590 |
-
troubleshoot_btn.click(
|
| 591 |
-
fn=run_troubleshoot,
|
| 592 |
-
inputs=[troubleshoot_device, troubleshoot_text],
|
| 593 |
-
outputs=[
|
| 594 |
-
troubleshoot_md,
|
| 595 |
-
troubleshoot_log,
|
| 596 |
-
troubleshoot_actions,
|
| 597 |
-
troubleshoot_conf,
|
| 598 |
-
troubleshoot_state,
|
| 599 |
-
],
|
| 600 |
-
)
|
| 601 |
-
execute_btn.click(
|
| 602 |
-
fn=execute_recovery_plan_wrapper,
|
| 603 |
-
inputs=[troubleshoot_device, troubleshoot_text],
|
| 604 |
-
outputs=[execute_summary, execute_log],
|
| 605 |
-
)
|
| 606 |
-
reset_btn.click(
|
| 607 |
-
fn=reset_state,
|
| 608 |
-
inputs=[],
|
| 609 |
-
outputs=[reset_md],
|
| 610 |
-
)
|
| 611 |
run_pipeline_btn.click(
|
| 612 |
fn=run_pipeline,
|
| 613 |
inputs=[pipeline_input],
|
| 614 |
outputs=[pipeline_status, sot_output, bom_output, setup_output, diagram_output],
|
| 615 |
)
|
| 616 |
-
synapse_btn.click(fn=load_synapse_log, inputs=None, outputs=synapse_md)
|
| 617 |
|
| 618 |
# Lab Management click handlers
|
| 619 |
refresh_projects_btn.click(
|
|
|
|
| 205 |
|
| 206 |
device_choices = topology.list_devices()
|
| 207 |
|
| 208 |
+
# Main Pipeline UI
|
| 209 |
+
gr.Markdown("""### 🌿 Network Automation Pipeline
|
| 210 |
+
**From Consultation → Production**
|
| 211 |
+
|
| 212 |
+
Describe your network in plain English. Overgrowth handles the rest:
|
| 213 |
+
1. 💬 **Consultation** - Capture requirements
|
| 214 |
+
2. 📋 **Source of Truth** - Generate network data model
|
| 215 |
+
3. 📊 **Diagram** - Visualize topology
|
| 216 |
+
4. 🛒 **Bill of Materials** - Hardware shopping list
|
| 217 |
+
5. 🔧 **Setup Guide** - Human deployment steps + OOB network
|
| 218 |
+
6. 🤖 **Autonomous Deploy** - AI configures devices (Ansible/Netmiko)
|
| 219 |
+
7. 👁️ **Observability** - Monitoring, SNMP, topology discovery
|
| 220 |
+
8. ✅ **Validation** - pytest-based network testing & compliance
|
| 221 |
+
""")
|
| 222 |
+
|
| 223 |
with gr.Row(elem_classes=["og-main-row"]):
|
| 224 |
with gr.Column(scale=1, elem_classes=["og-panel"]):
|
| 225 |
+
pipeline_input = gr.Textbox(
|
| 226 |
+
label="Describe Your Network",
|
| 227 |
placeholder=(
|
| 228 |
+
"Example: We're a coffee shop chain with 3 locations. "
|
| 229 |
+
"We need WiFi for customers, POS systems with payment processing, "
|
| 230 |
+
"security cameras, and secure VPN to HQ for centralized management. "
|
| 231 |
+
"Each location has ~50 customers at peak time."
|
| 232 |
),
|
| 233 |
+
lines=10,
|
| 234 |
)
|
| 235 |
+
run_pipeline_btn = gr.Button("🚀 Run Full Pipeline", variant="primary", size="lg")
|
| 236 |
+
|
| 237 |
+
gr.Markdown("#### 🔄 Tool Calls & Logs")
|
| 238 |
+
tool_log_md = gr.Markdown(label="MCP Activity")
|
| 239 |
|
| 240 |
with gr.Column(scale=2, elem_classes=["og-panel", "og-tabs"]):
|
| 241 |
+
gr.Markdown("#### 📦 Pipeline Outputs")
|
| 242 |
+
pipeline_status = gr.Markdown(label="Status")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 243 |
|
| 244 |
+
with gr.Tabs():
|
| 245 |
+
with gr.Tab("📋 Source of Truth"):
|
| 246 |
+
sot_output = gr.Code(label="Network Model (YAML)", language="yaml", lines=20)
|
| 247 |
|
| 248 |
+
with gr.Tab("🛒 Bill of Materials"):
|
| 249 |
+
bom_output = gr.Markdown(label="Shopping List")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 250 |
|
| 251 |
+
with gr.Tab("🔧 Setup Guide"):
|
| 252 |
+
setup_output = gr.Markdown(label="Deployment Guide")
|
| 253 |
+
|
| 254 |
+
with gr.Tab("📊 Diagram"):
|
| 255 |
+
diagram_output = gr.Textbox(label="Network Diagram", lines=25, max_lines=50)
|
| 256 |
+
|
| 257 |
+
# Advanced tabs (collapsed by default)
|
| 258 |
+
with gr.Accordion("🔧 Advanced Operations", open=False):
|
| 259 |
+
with gr.Tabs():
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 260 |
with gr.Tab("Build Network"):
|
| 261 |
gr.Markdown("### 🌱 Build Network from Description\nDescribe your network needs in plain English - Overgrowth builds and configures it automatically.")
|
| 262 |
|
|
|
|
| 350 |
backup_btn = gr.Button("Backup Config", variant="secondary")
|
| 351 |
backup_result = gr.Markdown(label="Backup Result")
|
| 352 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 353 |
# Lab Management handlers
|
| 354 |
def refresh_projects():
|
| 355 |
projects = get_lab_projects()
|
|
|
|
| 522 |
error_json = json.dumps(result, indent=2)
|
| 523 |
return error_msg, error_json
|
| 524 |
|
| 525 |
+
# Event Handlers
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 526 |
run_pipeline_btn.click(
|
| 527 |
fn=run_pipeline,
|
| 528 |
inputs=[pipeline_input],
|
| 529 |
outputs=[pipeline_status, sot_output, bom_output, setup_output, diagram_output],
|
| 530 |
)
|
|
|
|
| 531 |
|
| 532 |
# Lab Management click handlers
|
| 533 |
refresh_projects_btn.click(
|