Update app.py
Browse files
app.py
CHANGED
|
@@ -10,9 +10,10 @@ import uuid
|
|
| 10 |
from dataclasses import dataclass, asdict
|
| 11 |
from typing import List, Dict, Optional, Any
|
| 12 |
from openai import AsyncOpenAI
|
|
|
|
| 13 |
#================================================================================
|
| 14 |
-
|
| 15 |
-
#
|
| 16 |
COMPONENT_HIERARCHY = {
|
| 17 |
"HIGH_LEVEL": {
|
| 18 |
"CLASS": {
|
|
@@ -77,9 +78,66 @@ COMPONENT_HIERARCHY = {
|
|
| 77 |
"icon": "π¦",
|
| 78 |
"shape": "folder",
|
| 79 |
"sub_components": ["PACKAGE", "SUBPACKAGE", "PACKAGE_DEPENDENCY", "IMPORT", "ACCESS"]
|
| 80 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 81 |
}
|
| 82 |
}
|
|
|
|
| 83 |
# Complete Component Information with Configuration
|
| 84 |
COMPONENT_INFO = {
|
| 85 |
# ===================================
|
|
@@ -534,186 +592,7 @@ COMPONENT_INFO = {
|
|
| 534 |
"name": {"type": "text", "label": "Dependency Name", "default": "Dependency"},
|
| 535 |
"stereotype": {"type": "text", "label": "Stereotype", "default": "<<import>>"},
|
| 536 |
}
|
| 537 |
-
}
|
| 538 |
-
}
|
| 539 |
-
# Enhanced Example workflows
|
| 540 |
-
EXAMPLE_WORKFLOWS = {
|
| 541 |
-
"E-Commerce Class Diagram": {
|
| 542 |
-
"description": "Object-oriented design for e-commerce system",
|
| 543 |
-
"nodes": [
|
| 544 |
-
{"id": "user", "type": "CLASS", "x": 100, "y": 100},
|
| 545 |
-
{"id": "product", "type": "CLASS", "x": 300, "y": 100},
|
| 546 |
-
{"id": "order", "type": "CLASS", "x": 500, "y": 100},
|
| 547 |
-
{"id": "payment", "type": "CLASS", "x": 700, "y": 100},
|
| 548 |
-
{"id": "cart", "type": "CLASS", "x": 300, "y": 300},
|
| 549 |
-
{"id": "inventory", "type": "CLASS", "x": 500, "y": 300}
|
| 550 |
-
],
|
| 551 |
-
"connections": [
|
| 552 |
-
{"from": "user", "to": "order", "type": "AGGREGATION"},
|
| 553 |
-
{"from": "order", "to": "product", "type": "COMPOSITION"},
|
| 554 |
-
{"from": "order", "to": "payment", "type": "AGGREGATION"},
|
| 555 |
-
{"from": "user", "to": "cart", "type": "AGGREGATION"},
|
| 556 |
-
{"from": "cart", "to": "product", "type": "AGGREGATION"},
|
| 557 |
-
{"from": "product", "to": "inventory", "type": "AGGREGATION"}
|
| 558 |
-
]
|
| 559 |
-
},
|
| 560 |
-
|
| 561 |
-
"User Authentication Use Case": {
|
| 562 |
-
"description": "Use case diagram for user authentication system",
|
| 563 |
-
"nodes": [
|
| 564 |
-
{"id": "user", "type": "ACTOR", "x": 50, "y": 200},
|
| 565 |
-
{"id": "admin", "type": "ACTOR", "x": 50, "y": 300},
|
| 566 |
-
{"id": "login", "type": "USECASE", "x": 250, "y": 150},
|
| 567 |
-
{"id": "register", "type": "USECASE", "x": 250, "y": 250},
|
| 568 |
-
{"id": "reset_password", "type": "USECASE", "x": 250, "y": 350},
|
| 569 |
-
{"id": "admin_panel", "type": "USECASE", "x": 450, "y": 300},
|
| 570 |
-
{"id": "system_boundary", "type": "SYSTEM_BOUNDARY", "x": 150, "y": 100}
|
| 571 |
-
],
|
| 572 |
-
"connections": [
|
| 573 |
-
{"from": "user", "to": "login"},
|
| 574 |
-
{"from": "user", "to": "register"},
|
| 575 |
-
{"from": "user", "to": "reset_password"},
|
| 576 |
-
{"from": "admin", "to": "admin_panel"},
|
| 577 |
-
{"from": "admin", "to": "login"},
|
| 578 |
-
{"from": "login", "to": "reset_password", "type": "EXTEND"}
|
| 579 |
-
]
|
| 580 |
-
},
|
| 581 |
-
|
| 582 |
-
"Order Processing Sequence": {
|
| 583 |
-
"description": "Sequence diagram for order processing workflow",
|
| 584 |
-
"nodes": [
|
| 585 |
-
{"id": "customer", "type": "LIFELINE", "x": 100, "y": 50},
|
| 586 |
-
{"id": "ui", "type": "LIFELINE", "x": 250, "y": 50},
|
| 587 |
-
{"id": "order_service", "type": "LIFELINE", "x": 400, "y": 50},
|
| 588 |
-
{"id": "payment_service", "type": "LIFELINE", "x": 550, "y": 50},
|
| 589 |
-
{"id": "inventory_service", "type": "LIFELINE", "x": 700, "y": 50}
|
| 590 |
-
],
|
| 591 |
-
"connections": [
|
| 592 |
-
{"from": "customer", "to": "ui", "type": "MESSAGE", "label": "placeOrder()"},
|
| 593 |
-
{"from": "ui", "to": "order_service", "type": "MESSAGE", "label": "createOrder()"},
|
| 594 |
-
{"from": "order_service", "to": "inventory_service", "type": "MESSAGE", "label": "checkAvailability()"},
|
| 595 |
-
{"from": "inventory_service", "to": "order_service", "type": "MESSAGE", "label": "availabilityConfirmed()"},
|
| 596 |
-
{"from": "order_service", "to": "payment_service", "type": "MESSAGE", "label": "processPayment()"},
|
| 597 |
-
{"from": "payment_service", "to": "order_service", "type": "MESSAGE", "label": "paymentConfirmed()"},
|
| 598 |
-
{"from": "order_service", "to": "ui", "type": "MESSAGE", "label": "orderConfirmed()"},
|
| 599 |
-
{"from": "ui", "to": "customer", "type": "MESSAGE", "label": "showConfirmation()"}
|
| 600 |
-
]
|
| 601 |
-
},
|
| 602 |
-
|
| 603 |
-
"User State Machine": {
|
| 604 |
-
"description": "State machine for user account states",
|
| 605 |
-
"nodes": [
|
| 606 |
-
{"id": "pending", "type": "STATE", "x": 100, "y": 100},
|
| 607 |
-
{"id": "active", "type": "STATE", "x": 300, "y": 100},
|
| 608 |
-
{"id": "suspended", "type": "STATE", "x": 500, "y": 100},
|
| 609 |
-
{"id": "deleted", "type": "STATE", "x": 300, "y": 300},
|
| 610 |
-
{"id": "start", "type": "START_NODE", "x": 50, "y": 100},
|
| 611 |
-
{"id": "end", "type": "END_NODE", "x": 300, "y": 400}
|
| 612 |
-
],
|
| 613 |
-
"connections": [
|
| 614 |
-
{"from": "start", "to": "pending"},
|
| 615 |
-
{"from": "pending", "to": "active", "type": "TRANSITION", "label": "approveAccount()"},
|
| 616 |
-
{"from": "active", "to": "suspended", "type": "TRANSITION", "label": "suspendAccount()"},
|
| 617 |
-
{"from": "suspended", "to": "active", "type": "TRANSITION", "label": "activateAccount()"},
|
| 618 |
-
{"from": "active", "to": "deleted", "type": "TRANSITION", "label": "deleteAccount()"},
|
| 619 |
-
{"from": "suspended", "to": "deleted", "type": "TRANSITION", "label": "deleteAccount()"},
|
| 620 |
-
{"from": "deleted", "to": "end"}
|
| 621 |
-
]
|
| 622 |
},
|
| 623 |
-
|
| 624 |
-
"Document Management Activity": {
|
| 625 |
-
"description": "Activity diagram for document management process",
|
| 626 |
-
"nodes": [
|
| 627 |
-
{"id": "start", "type": "START_NODE", "x": 200, "y": 50},
|
| 628 |
-
{"id": "upload", "type": "ACTION", "x": 200, "y": 150},
|
| 629 |
-
{"id": "validate", "type": "DECISION", "x": 200, "y": 250},
|
| 630 |
-
{"id": "process", "type": "ACTION", "x": 200, "y": 350},
|
| 631 |
-
{"id": "store", "type": "ACTION", "x": 200, "y": 450},
|
| 632 |
-
{"id": "notify", "type": "ACTION", "x": 200, "y": 550},
|
| 633 |
-
{"id": "end", "type": "END_NODE", "x": 200, "y": 650},
|
| 634 |
-
{"id": "error", "type": "ACTION", "x": 400, "y": 350}
|
| 635 |
-
],
|
| 636 |
-
"connections": [
|
| 637 |
-
{"from": "start", "to": "upload"},
|
| 638 |
-
{"from": "upload", "to": "validate"},
|
| 639 |
-
{"from": "validate", "to": "process", "label": "[valid]"},
|
| 640 |
-
{"from": "validate", "to": "error", "label": "[invalid]"},
|
| 641 |
-
{"from": "error", "to": "end"},
|
| 642 |
-
{"from": "process", "to": "store"},
|
| 643 |
-
{"from": "store", "to": "notify"},
|
| 644 |
-
{"from": "notify", "to": "end"}
|
| 645 |
-
]
|
| 646 |
-
}
|
| 647 |
-
}
|
| 648 |
-
#================================================================================
|
| 649 |
-
#================================================================================
|
| 650 |
-
## AGENTIC TOOLBOX - FIXED VERSION
|
| 651 |
-
#================================================================================
|
| 652 |
-
|
| 653 |
-
# Unified Hierarchical Component definitions
|
| 654 |
-
COMPONENT_HIERARCHY = {
|
| 655 |
-
"HIGH_LEVEL": {
|
| 656 |
-
"SYSTEM": {
|
| 657 |
-
"description": "Top-level system architecture containing all components",
|
| 658 |
-
"color": "#333333",
|
| 659 |
-
"icon": "π",
|
| 660 |
-
"shape": "folder",
|
| 661 |
-
"sub_components": ["AGENT", "USER", "TOOL", "DATA", "PROCESSOR", "ROUTER", "INFRASTRUCTURE", "CONFIG"]
|
| 662 |
-
},
|
| 663 |
-
"AGENT": {
|
| 664 |
-
"description": "Autonomous reasoning and decision-making units",
|
| 665 |
-
"color": "#4CAF50",
|
| 666 |
-
"icon": "π€",
|
| 667 |
-
"shape": "rect",
|
| 668 |
-
"sub_components": ["REASONING_AGENT", "ACTION_AGENT", "PLANNER_AGENT", "REACT_AGENT", "MULTI_AGENT"]
|
| 669 |
-
},
|
| 670 |
-
"USER": {
|
| 671 |
-
"description": "User interaction points and interfaces",
|
| 672 |
-
"color": "#9C27B0",
|
| 673 |
-
"icon": "π€",
|
| 674 |
-
"shape": "ellipse",
|
| 675 |
-
"sub_components": ["USER_INPUT", "USER_OUTPUT", "MULTIMODAL_INTERFACE"]
|
| 676 |
-
},
|
| 677 |
-
"TOOL": {
|
| 678 |
-
"description": "External functions and capabilities",
|
| 679 |
-
"color": "#795548",
|
| 680 |
-
"icon": "π§",
|
| 681 |
-
"shape": "hexagon",
|
| 682 |
-
"sub_components": ["MCP_TOOL", "API_TOOL", "LOCAL_TOOL", "AGENT_TOOL", "FUNCTION_TOOL"]
|
| 683 |
-
},
|
| 684 |
-
"DATA": {
|
| 685 |
-
"description": "Data sources and storage systems",
|
| 686 |
-
"color": "#009688",
|
| 687 |
-
"icon": "πΎ",
|
| 688 |
-
"shape": "cylinder",
|
| 689 |
-
"sub_components": ["KNOWLEDGE_BASE", "VECTOR_DB", "DOCUMENT_STORE", "CACHE", "MEMORY"]
|
| 690 |
-
},
|
| 691 |
-
"PROCESSOR": {
|
| 692 |
-
"description": "Data processing and transformation units",
|
| 693 |
-
"color": "#2196F3",
|
| 694 |
-
"icon": "βοΈ",
|
| 695 |
-
"shape": "rect",
|
| 696 |
-
"sub_components": ["QUERY_PROCESSOR", "CONTENT_RETRIEVAL", "PROMPT_TEMPLATE", "RESPONSE_FORMATTER"]
|
| 697 |
-
},
|
| 698 |
-
"ROUTER": {
|
| 699 |
-
"description": "Decision points and workflow routing",
|
| 700 |
-
"color": "#FF9800",
|
| 701 |
-
"icon": "π―",
|
| 702 |
-
"shape": "diamond",
|
| 703 |
-
"sub_components": ["INTENT_DISCOVERY", "MODEL_SELECTOR", "WORKFLOW_ROUTER", "VALIDATOR"]
|
| 704 |
-
},
|
| 705 |
-
"INFRASTRUCTURE": {
|
| 706 |
-
"description": "System infrastructure and services",
|
| 707 |
-
"color": "#FF5722",
|
| 708 |
-
"icon": "π",
|
| 709 |
-
"shape": "rect",
|
| 710 |
-
"sub_components": ["PROVIDER", "MONITOR", "FALLBACK", "ORCHESTRATOR"]
|
| 711 |
-
},
|
| 712 |
-
}
|
| 713 |
-
}
|
| 714 |
-
|
| 715 |
-
# Complete Component Information - ENSURED ALL HAVE config_fields
|
| 716 |
-
COMPONENT_INFO = {
|
| 717 |
# SYSTEM
|
| 718 |
"SYSTEM": {
|
| 719 |
"description": "Top-level system architecture containing all components",
|
|
@@ -1159,8 +1038,114 @@ COMPONENT_INFO = {
|
|
| 1159 |
},
|
| 1160 |
}
|
| 1161 |
|
| 1162 |
-
# Example workflows
|
| 1163 |
EXAMPLE_WORKFLOWS = {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1164 |
"Simple Chat Agent": {
|
| 1165 |
"description": "Basic conversational agent with single LLM call",
|
| 1166 |
"nodes": [
|
|
@@ -1300,8 +1285,8 @@ EXAMPLE_WORKFLOWS = {
|
|
| 1300 |
]
|
| 1301 |
}
|
| 1302 |
}
|
| 1303 |
-
|
| 1304 |
#================================================================================
|
|
|
|
| 1305 |
# Combine all components
|
| 1306 |
ALL_COMPONENTS = {}
|
| 1307 |
for category, components in COMPONENT_HIERARCHY["HIGH_LEVEL"].items():
|
|
@@ -1737,13 +1722,7 @@ def create_workflow_ui():
|
|
| 1737 |
)
|
| 1738 |
component_buttons.append((btn, comp_type))
|
| 1739 |
|
| 1740 |
-
|
| 1741 |
-
gr.Markdown("## π Connections")
|
| 1742 |
-
with gr.Row():
|
| 1743 |
-
from_node = gr.Dropdown(label="From", choices=[], interactive=True, scale=2)
|
| 1744 |
-
to_node = gr.Dropdown(label="To", choices=[], interactive=True, scale=2)
|
| 1745 |
-
connect_btn = gr.Button("β‘οΈ Connect Nodes", variant="secondary")
|
| 1746 |
-
|
| 1747 |
gr.Markdown("---")
|
| 1748 |
gr.Markdown("## π Examples")
|
| 1749 |
example_dropdown = gr.Dropdown(
|
|
@@ -1838,7 +1817,14 @@ def create_workflow_ui():
|
|
| 1838 |
with gr.Row():
|
| 1839 |
save_config_btn = gr.Button("πΎ Save Config", variant="primary")
|
| 1840 |
cancel_config_btn = gr.Button("β Cancel", variant="secondary")
|
| 1841 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1842 |
# Right Sidebar - Information and Export
|
| 1843 |
with gr.Column(scale=1, min_width=300):
|
| 1844 |
gr.Markdown("## π Workflow Information")
|
|
@@ -2173,138 +2159,157 @@ def create_main_workflow_ui():
|
|
| 2173 |
pending_component_type = gr.State("")
|
| 2174 |
editing_node_id = gr.State("")
|
| 2175 |
|
| 2176 |
-
|
| 2177 |
-
|
| 2178 |
-
|
| 2179 |
-
|
| 2180 |
-
|
| 2181 |
-
|
| 2182 |
-
|
| 2183 |
-
|
| 2184 |
-
|
| 2185 |
-
|
| 2186 |
-
|
| 2187 |
-
|
| 2188 |
-
btn = gr.Button(
|
| 2189 |
-
f"{info['icon']} Add {category}",
|
| 2190 |
-
size="sm",
|
| 2191 |
-
variant="primary"
|
| 2192 |
-
)
|
| 2193 |
-
component_buttons.append((btn, category))
|
| 2194 |
-
|
| 2195 |
-
if info.get('sub_components'):
|
| 2196 |
-
gr.Markdown("**Specialized:**")
|
| 2197 |
-
for sub_comp in info['sub_components']:
|
| 2198 |
-
if sub_comp in COMPONENT_INFO:
|
| 2199 |
-
sub_info = COMPONENT_INFO[sub_comp]
|
| 2200 |
-
sub_btn = gr.Button(
|
| 2201 |
-
f"{sub_info['icon']} {sub_comp.replace('_', ' ').title()}",
|
| 2202 |
-
size="sm"
|
| 2203 |
-
)
|
| 2204 |
-
component_buttons.append((sub_btn, sub_comp))
|
| 2205 |
-
|
| 2206 |
-
with gr.TabItem("All"):
|
| 2207 |
-
for comp_type, comp_info in COMPONENT_INFO.items():
|
| 2208 |
btn = gr.Button(
|
| 2209 |
-
f"{
|
| 2210 |
size="sm",
|
| 2211 |
-
variant="
|
| 2212 |
)
|
| 2213 |
-
component_buttons.append((btn,
|
| 2214 |
-
|
| 2215 |
-
|
| 2216 |
-
|
| 2217 |
-
|
| 2218 |
-
|
| 2219 |
-
|
| 2220 |
-
|
| 2221 |
-
|
| 2222 |
-
|
| 2223 |
-
|
| 2224 |
-
|
| 2225 |
-
|
| 2226 |
-
|
| 2227 |
-
|
| 2228 |
-
|
| 2229 |
-
|
| 2230 |
-
|
| 2231 |
-
|
| 2232 |
-
|
| 2233 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2234 |
|
| 2235 |
# Center
|
| 2236 |
-
|
| 2237 |
-
|
| 2238 |
-
|
| 2239 |
-
|
|
|
|
|
|
|
| 2240 |
with gr.Row():
|
| 2241 |
-
|
| 2242 |
-
|
| 2243 |
-
|
| 2244 |
-
|
| 2245 |
with gr.Row():
|
| 2246 |
-
|
| 2247 |
-
|
| 2248 |
|
| 2249 |
-
|
| 2250 |
-
|
| 2251 |
-
|
| 2252 |
-
|
| 2253 |
-
|
| 2254 |
-
|
|
|
|
|
|
|
| 2255 |
|
| 2256 |
-
|
| 2257 |
-
|
|
|
|
|
|
|
| 2258 |
|
| 2259 |
-
|
| 2260 |
-
gr.Markdown("### βοΈ Configuration")
|
| 2261 |
-
config_display = gr.JSON(label="Current Config")
|
| 2262 |
|
| 2263 |
-
|
| 2264 |
-
with gr.Column(scale=1, min_width=300):
|
| 2265 |
-
gr.Markdown("## π Info")
|
| 2266 |
-
|
| 2267 |
-
with gr.Accordion("π JSON", open=False):
|
| 2268 |
-
workflow_json = gr.JSON(label="Workflow Data")
|
| 2269 |
-
|
| 2270 |
-
with gr.Accordion("π Component", open=True):
|
| 2271 |
-
component_info = gr.Markdown("Select a component")
|
| 2272 |
-
|
| 2273 |
-
gr.Markdown("---")
|
| 2274 |
-
gr.Markdown("## π Report")
|
| 2275 |
-
report_btn = gr.Button("π Generate", variant="primary")
|
| 2276 |
-
report_output = gr.Textbox(label="Report", lines=10, interactive=False)
|
| 2277 |
-
|
| 2278 |
-
gr.Markdown("---")
|
| 2279 |
-
download_files = gr.Files(label="π₯ Downloads")
|
| 2280 |
|
| 2281 |
-
#
|
| 2282 |
-
with gr.Column(
|
|
|
|
|
|
|
|
|
|
| 2283 |
with gr.Row():
|
| 2284 |
-
gr.
|
| 2285 |
-
|
| 2286 |
-
|
| 2287 |
-
with gr.Column(scale=2, min_width=400, elem_classes=["modal-content"]):
|
| 2288 |
with gr.Row():
|
| 2289 |
-
|
| 2290 |
-
|
| 2291 |
-
|
| 2292 |
-
|
| 2293 |
-
|
| 2294 |
-
|
| 2295 |
-
|
| 2296 |
-
|
| 2297 |
-
interactive=True
|
| 2298 |
-
)
|
| 2299 |
-
config_inputs.append(config_input)
|
| 2300 |
|
|
|
|
| 2301 |
with gr.Row():
|
| 2302 |
-
|
| 2303 |
-
|
| 2304 |
-
|
| 2305 |
-
|
| 2306 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2307 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2308 |
# Add custom CSS for modal styling
|
| 2309 |
demo.css = """
|
| 2310 |
.modal-overlay {
|
|
@@ -2333,7 +2338,7 @@ def create_main_workflow_ui():
|
|
| 2333 |
margin-bottom: 10px !important;
|
| 2334 |
}
|
| 2335 |
"""
|
| 2336 |
-
|
| 2337 |
# Helper functions
|
| 2338 |
def get_full_state():
|
| 2339 |
svg = workflow.render_svg()
|
|
@@ -2451,7 +2456,7 @@ def create_main_workflow_ui():
|
|
| 2451 |
def close_modal():
|
| 2452 |
"""Close modal and reset state"""
|
| 2453 |
return [gr.update(visible=False), "", ""]
|
| 2454 |
-
|
| 2455 |
# Connect component buttons
|
| 2456 |
for btn, comp_type in component_buttons:
|
| 2457 |
btn.click(
|
|
@@ -2483,7 +2488,7 @@ def create_main_workflow_ui():
|
|
| 2483 |
# Close modal actions
|
| 2484 |
cancel_btn.click(close_modal, outputs=[config_modal, pending_component_type, editing_node_id])
|
| 2485 |
close_btn.click(close_modal, outputs=[config_modal, pending_component_type, editing_node_id])
|
| 2486 |
-
|
| 2487 |
# Navigation and other interactions remain the same...
|
| 2488 |
def navigate(direction):
|
| 2489 |
if workflow.nodes:
|
|
@@ -2503,7 +2508,7 @@ def create_main_workflow_ui():
|
|
| 2503 |
for btn, dx, dy in [(move_left_btn, -20, 0), (move_right_btn, 20, 0), (move_up_btn, 0, -20), (move_down_btn, 0, 20)]:
|
| 2504 |
btn.click(lambda dx=dx, dy=dy: (workflow.move_selected_node(dx, dy) or get_full_state()),
|
| 2505 |
outputs=[canvas, from_node, to_node, selected_node_info, config_display, workflow_json, component_info])
|
| 2506 |
-
|
| 2507 |
# Other actions
|
| 2508 |
connect_btn.click(lambda f, t: (workflow.add_connection(f, t) or get_full_state()) if f and t else get_full_state(),
|
| 2509 |
inputs=[from_node, to_node], outputs=[canvas, from_node, to_node, selected_node_info, config_display, workflow_json, component_info])
|
|
@@ -2516,7 +2521,7 @@ def create_main_workflow_ui():
|
|
| 2516 |
|
| 2517 |
clear_btn.click(lambda: (workflow.nodes.clear(), workflow.connections.clear(), setattr(workflow, 'node_counter', 0), setattr(workflow, 'selected_node', None), get_full_state())[-1],
|
| 2518 |
outputs=[canvas, from_node, to_node, selected_node_info, config_display, workflow_json, component_info])
|
| 2519 |
-
|
| 2520 |
# Export
|
| 2521 |
def export():
|
| 2522 |
wf = workflow.get_workflow_json()
|
|
@@ -2526,8 +2531,10 @@ def create_main_workflow_ui():
|
|
| 2526 |
|
| 2527 |
svg_path = tempfile.mktemp(suffix="_workflow.svg")
|
| 2528 |
with open(svg_path, "w") as f:
|
| 2529 |
-
|
| 2530 |
-
|
|
|
|
|
|
|
| 2531 |
return [json_path, svg_path]
|
| 2532 |
|
| 2533 |
download_btn.click(export, outputs=[download_files])
|
|
@@ -2540,7 +2547,7 @@ def create_main_workflow_ui():
|
|
| 2540 |
return f"Error: {str(e)}\n\nEnsure LM Studio is running."
|
| 2541 |
|
| 2542 |
report_btn.click(gen_report, outputs=[report_output])
|
| 2543 |
-
|
| 2544 |
# Initialize
|
| 2545 |
demo.load(get_full_state, outputs=[canvas, from_node, to_node, selected_node_info, config_display, workflow_json, component_info])
|
| 2546 |
|
|
|
|
| 10 |
from dataclasses import dataclass, asdict
|
| 11 |
from typing import List, Dict, Optional, Any
|
| 12 |
from openai import AsyncOpenAI
|
| 13 |
+
|
| 14 |
#================================================================================
|
| 15 |
+
# Unified Hierarchical Component definitions for UML and Object-Oriented Design
|
| 16 |
+
# as well as agentic design
|
| 17 |
COMPONENT_HIERARCHY = {
|
| 18 |
"HIGH_LEVEL": {
|
| 19 |
"CLASS": {
|
|
|
|
| 78 |
"icon": "π¦",
|
| 79 |
"shape": "folder",
|
| 80 |
"sub_components": ["PACKAGE", "SUBPACKAGE", "PACKAGE_DEPENDENCY", "IMPORT", "ACCESS"]
|
| 81 |
+
},
|
| 82 |
+
"SYSTEM": {
|
| 83 |
+
"description": "Top-level system architecture containing all components",
|
| 84 |
+
"color": "#333333",
|
| 85 |
+
"icon": "π",
|
| 86 |
+
"shape": "folder",
|
| 87 |
+
"sub_components": ["AGENT", "USER", "TOOL", "DATA", "PROCESSOR", "ROUTER", "INFRASTRUCTURE", "CONFIG"]
|
| 88 |
+
},
|
| 89 |
+
"AGENT": {
|
| 90 |
+
"description": "Autonomous reasoning and decision-making units",
|
| 91 |
+
"color": "#4CAF50",
|
| 92 |
+
"icon": "π€",
|
| 93 |
+
"shape": "rect",
|
| 94 |
+
"sub_components": ["REASONING_AGENT", "ACTION_AGENT", "PLANNER_AGENT", "REACT_AGENT", "MULTI_AGENT"]
|
| 95 |
+
},
|
| 96 |
+
"USER": {
|
| 97 |
+
"description": "User interaction points and interfaces",
|
| 98 |
+
"color": "#9C27B0",
|
| 99 |
+
"icon": "π€",
|
| 100 |
+
"shape": "ellipse",
|
| 101 |
+
"sub_components": ["USER_INPUT", "USER_OUTPUT", "MULTIMODAL_INTERFACE"]
|
| 102 |
+
},
|
| 103 |
+
"TOOL": {
|
| 104 |
+
"description": "External functions and capabilities",
|
| 105 |
+
"color": "#795548",
|
| 106 |
+
"icon": "π§",
|
| 107 |
+
"shape": "hexagon",
|
| 108 |
+
"sub_components": ["MCP_TOOL", "API_TOOL", "LOCAL_TOOL", "AGENT_TOOL", "FUNCTION_TOOL"]
|
| 109 |
+
},
|
| 110 |
+
"DATA": {
|
| 111 |
+
"description": "Data sources and storage systems",
|
| 112 |
+
"color": "#009688",
|
| 113 |
+
"icon": "πΎ",
|
| 114 |
+
"shape": "cylinder",
|
| 115 |
+
"sub_components": ["KNOWLEDGE_BASE", "VECTOR_DB", "DOCUMENT_STORE", "CACHE", "MEMORY"]
|
| 116 |
+
},
|
| 117 |
+
"PROCESSOR": {
|
| 118 |
+
"description": "Data processing and transformation units",
|
| 119 |
+
"color": "#2196F3",
|
| 120 |
+
"icon": "βοΈ",
|
| 121 |
+
"shape": "rect",
|
| 122 |
+
"sub_components": ["QUERY_PROCESSOR", "CONTENT_RETRIEVAL", "PROMPT_TEMPLATE", "RESPONSE_FORMATTER"]
|
| 123 |
+
},
|
| 124 |
+
"ROUTER": {
|
| 125 |
+
"description": "Decision points and workflow routing",
|
| 126 |
+
"color": "#FF9800",
|
| 127 |
+
"icon": "π―",
|
| 128 |
+
"shape": "diamond",
|
| 129 |
+
"sub_components": ["INTENT_DISCOVERY", "MODEL_SELECTOR", "WORKFLOW_ROUTER", "VALIDATOR"]
|
| 130 |
+
},
|
| 131 |
+
"INFRASTRUCTURE": {
|
| 132 |
+
"description": "System infrastructure and services",
|
| 133 |
+
"color": "#FF5722",
|
| 134 |
+
"icon": "π",
|
| 135 |
+
"shape": "rect",
|
| 136 |
+
"sub_components": ["PROVIDER", "MONITOR", "FALLBACK", "ORCHESTRATOR"]
|
| 137 |
+
},
|
| 138 |
}
|
| 139 |
}
|
| 140 |
+
|
| 141 |
# Complete Component Information with Configuration
|
| 142 |
COMPONENT_INFO = {
|
| 143 |
# ===================================
|
|
|
|
| 592 |
"name": {"type": "text", "label": "Dependency Name", "default": "Dependency"},
|
| 593 |
"stereotype": {"type": "text", "label": "Stereotype", "default": "<<import>>"},
|
| 594 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 595 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 596 |
# SYSTEM
|
| 597 |
"SYSTEM": {
|
| 598 |
"description": "Top-level system architecture containing all components",
|
|
|
|
| 1038 |
},
|
| 1039 |
}
|
| 1040 |
|
| 1041 |
+
# Enhanced Example workflows
|
| 1042 |
EXAMPLE_WORKFLOWS = {
|
| 1043 |
+
"E-Commerce Class Diagram": {
|
| 1044 |
+
"description": "Object-oriented design for e-commerce system",
|
| 1045 |
+
"nodes": [
|
| 1046 |
+
{"id": "user", "type": "CLASS", "x": 100, "y": 100},
|
| 1047 |
+
{"id": "product", "type": "CLASS", "x": 300, "y": 100},
|
| 1048 |
+
{"id": "order", "type": "CLASS", "x": 500, "y": 100},
|
| 1049 |
+
{"id": "payment", "type": "CLASS", "x": 700, "y": 100},
|
| 1050 |
+
{"id": "cart", "type": "CLASS", "x": 300, "y": 300},
|
| 1051 |
+
{"id": "inventory", "type": "CLASS", "x": 500, "y": 300}
|
| 1052 |
+
],
|
| 1053 |
+
"connections": [
|
| 1054 |
+
{"from": "user", "to": "order", "type": "AGGREGATION"},
|
| 1055 |
+
{"from": "order", "to": "product", "type": "COMPOSITION"},
|
| 1056 |
+
{"from": "order", "to": "payment", "type": "AGGREGATION"},
|
| 1057 |
+
{"from": "user", "to": "cart", "type": "AGGREGATION"},
|
| 1058 |
+
{"from": "cart", "to": "product", "type": "AGGREGATION"},
|
| 1059 |
+
{"from": "product", "to": "inventory", "type": "AGGREGATION"}
|
| 1060 |
+
]
|
| 1061 |
+
},
|
| 1062 |
+
|
| 1063 |
+
"User Authentication Use Case": {
|
| 1064 |
+
"description": "Use case diagram for user authentication system",
|
| 1065 |
+
"nodes": [
|
| 1066 |
+
{"id": "user", "type": "ACTOR", "x": 50, "y": 200},
|
| 1067 |
+
{"id": "admin", "type": "ACTOR", "x": 50, "y": 300},
|
| 1068 |
+
{"id": "login", "type": "USECASE", "x": 250, "y": 150},
|
| 1069 |
+
{"id": "register", "type": "USECASE", "x": 250, "y": 250},
|
| 1070 |
+
{"id": "reset_password", "type": "USECASE", "x": 250, "y": 350},
|
| 1071 |
+
{"id": "admin_panel", "type": "USECASE", "x": 450, "y": 300},
|
| 1072 |
+
{"id": "system_boundary", "type": "SYSTEM_BOUNDARY", "x": 150, "y": 100}
|
| 1073 |
+
],
|
| 1074 |
+
"connections": [
|
| 1075 |
+
{"from": "user", "to": "login"},
|
| 1076 |
+
{"from": "user", "to": "register"},
|
| 1077 |
+
{"from": "user", "to": "reset_password"},
|
| 1078 |
+
{"from": "admin", "to": "admin_panel"},
|
| 1079 |
+
{"from": "admin", "to": "login"},
|
| 1080 |
+
{"from": "login", "to": "reset_password", "type": "EXTEND"}
|
| 1081 |
+
]
|
| 1082 |
+
},
|
| 1083 |
+
|
| 1084 |
+
"Order Processing Sequence": {
|
| 1085 |
+
"description": "Sequence diagram for order processing workflow",
|
| 1086 |
+
"nodes": [
|
| 1087 |
+
{"id": "customer", "type": "LIFELINE", "x": 100, "y": 50},
|
| 1088 |
+
{"id": "ui", "type": "LIFELINE", "x": 250, "y": 50},
|
| 1089 |
+
{"id": "order_service", "type": "LIFELINE", "x": 400, "y": 50},
|
| 1090 |
+
{"id": "payment_service", "type": "LIFELINE", "x": 550, "y": 50},
|
| 1091 |
+
{"id": "inventory_service", "type": "LIFELINE", "x": 700, "y": 50}
|
| 1092 |
+
],
|
| 1093 |
+
"connections": [
|
| 1094 |
+
{"from": "customer", "to": "ui", "type": "MESSAGE", "label": "placeOrder()"},
|
| 1095 |
+
{"from": "ui", "to": "order_service", "type": "MESSAGE", "label": "createOrder()"},
|
| 1096 |
+
{"from": "order_service", "to": "inventory_service", "type": "MESSAGE", "label": "checkAvailability()"},
|
| 1097 |
+
{"from": "inventory_service", "to": "order_service", "type": "MESSAGE", "label": "availabilityConfirmed()"},
|
| 1098 |
+
{"from": "order_service", "to": "payment_service", "type": "MESSAGE", "label": "processPayment()"},
|
| 1099 |
+
{"from": "payment_service", "to": "order_service", "type": "MESSAGE", "label": "paymentConfirmed()"},
|
| 1100 |
+
{"from": "order_service", "to": "ui", "type": "MESSAGE", "label": "orderConfirmed()"},
|
| 1101 |
+
{"from": "ui", "to": "customer", "type": "MESSAGE", "label": "showConfirmation()"}
|
| 1102 |
+
]
|
| 1103 |
+
},
|
| 1104 |
+
|
| 1105 |
+
"User State Machine": {
|
| 1106 |
+
"description": "State machine for user account states",
|
| 1107 |
+
"nodes": [
|
| 1108 |
+
{"id": "pending", "type": "STATE", "x": 100, "y": 100},
|
| 1109 |
+
{"id": "active", "type": "STATE", "x": 300, "y": 100},
|
| 1110 |
+
{"id": "suspended", "type": "STATE", "x": 500, "y": 100},
|
| 1111 |
+
{"id": "deleted", "type": "STATE", "x": 300, "y": 300},
|
| 1112 |
+
{"id": "start", "type": "START_NODE", "x": 50, "y": 100},
|
| 1113 |
+
{"id": "end", "type": "END_NODE", "x": 300, "y": 400}
|
| 1114 |
+
],
|
| 1115 |
+
"connections": [
|
| 1116 |
+
{"from": "start", "to": "pending"},
|
| 1117 |
+
{"from": "pending", "to": "active", "type": "TRANSITION", "label": "approveAccount()"},
|
| 1118 |
+
{"from": "active", "to": "suspended", "type": "TRANSITION", "label": "suspendAccount()"},
|
| 1119 |
+
{"from": "suspended", "to": "active", "type": "TRANSITION", "label": "activateAccount()"},
|
| 1120 |
+
{"from": "active", "to": "deleted", "type": "TRANSITION", "label": "deleteAccount()"},
|
| 1121 |
+
{"from": "suspended", "to": "deleted", "type": "TRANSITION", "label": "deleteAccount()"},
|
| 1122 |
+
{"from": "deleted", "to": "end"}
|
| 1123 |
+
]
|
| 1124 |
+
},
|
| 1125 |
+
|
| 1126 |
+
"Document Management Activity": {
|
| 1127 |
+
"description": "Activity diagram for document management process",
|
| 1128 |
+
"nodes": [
|
| 1129 |
+
{"id": "start", "type": "START_NODE", "x": 200, "y": 50},
|
| 1130 |
+
{"id": "upload", "type": "ACTION", "x": 200, "y": 150},
|
| 1131 |
+
{"id": "validate", "type": "DECISION", "x": 200, "y": 250},
|
| 1132 |
+
{"id": "process", "type": "ACTION", "x": 200, "y": 350},
|
| 1133 |
+
{"id": "store", "type": "ACTION", "x": 200, "y": 450},
|
| 1134 |
+
{"id": "notify", "type": "ACTION", "x": 200, "y": 550},
|
| 1135 |
+
{"id": "end", "type": "END_NODE", "x": 200, "y": 650},
|
| 1136 |
+
{"id": "error", "type": "ACTION", "x": 400, "y": 350}
|
| 1137 |
+
],
|
| 1138 |
+
"connections": [
|
| 1139 |
+
{"from": "start", "to": "upload"},
|
| 1140 |
+
{"from": "upload", "to": "validate"},
|
| 1141 |
+
{"from": "validate", "to": "process", "label": "[valid]"},
|
| 1142 |
+
{"from": "validate", "to": "error", "label": "[invalid]"},
|
| 1143 |
+
{"from": "error", "to": "end"},
|
| 1144 |
+
{"from": "process", "to": "store"},
|
| 1145 |
+
{"from": "store", "to": "notify"},
|
| 1146 |
+
{"from": "notify", "to": "end"}
|
| 1147 |
+
]
|
| 1148 |
+
},
|
| 1149 |
"Simple Chat Agent": {
|
| 1150 |
"description": "Basic conversational agent with single LLM call",
|
| 1151 |
"nodes": [
|
|
|
|
| 1285 |
]
|
| 1286 |
}
|
| 1287 |
}
|
|
|
|
| 1288 |
#================================================================================
|
| 1289 |
+
|
| 1290 |
# Combine all components
|
| 1291 |
ALL_COMPONENTS = {}
|
| 1292 |
for category, components in COMPONENT_HIERARCHY["HIGH_LEVEL"].items():
|
|
|
|
| 1722 |
)
|
| 1723 |
component_buttons.append((btn, comp_type))
|
| 1724 |
|
| 1725 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1726 |
gr.Markdown("---")
|
| 1727 |
gr.Markdown("## π Examples")
|
| 1728 |
example_dropdown = gr.Dropdown(
|
|
|
|
| 1817 |
with gr.Row():
|
| 1818 |
save_config_btn = gr.Button("πΎ Save Config", variant="primary")
|
| 1819 |
cancel_config_btn = gr.Button("β Cancel", variant="secondary")
|
| 1820 |
+
with gr.Row():
|
| 1821 |
+
gr.Markdown("---")
|
| 1822 |
+
gr.Markdown("## π Connections")
|
| 1823 |
+
with gr.Row():
|
| 1824 |
+
from_node = gr.Dropdown(label="From", choices=[], interactive=True, scale=2)
|
| 1825 |
+
to_node = gr.Dropdown(label="To", choices=[], interactive=True, scale=2)
|
| 1826 |
+
connect_btn = gr.Button("β‘οΈ Connect Nodes", variant="secondary")
|
| 1827 |
+
|
| 1828 |
# Right Sidebar - Information and Export
|
| 1829 |
with gr.Column(scale=1, min_width=300):
|
| 1830 |
gr.Markdown("## π Workflow Information")
|
|
|
|
| 2159 |
pending_component_type = gr.State("")
|
| 2160 |
editing_node_id = gr.State("")
|
| 2161 |
|
| 2162 |
+
#================================================================================
|
| 2163 |
+
# Left Sidebar
|
| 2164 |
+
with gr.Sidebar(open=True,label = "Components",width=600, position = "right"):
|
| 2165 |
+
gr.Markdown("## π Component Library")
|
| 2166 |
+
|
| 2167 |
+
with gr.Tabs():
|
| 2168 |
+
with gr.TabItem("Categories"):
|
| 2169 |
+
component_buttons = []
|
| 2170 |
+
for category, info in COMPONENT_HIERARCHY["HIGH_LEVEL"].items():
|
| 2171 |
+
with gr.TabItem(f"{info['icon']} {category}"):
|
| 2172 |
+
gr.Markdown(f"*{info['description']}*")
|
| 2173 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2174 |
btn = gr.Button(
|
| 2175 |
+
f"{info['icon']} Add {category}",
|
| 2176 |
size="sm",
|
| 2177 |
+
variant="primary"
|
| 2178 |
)
|
| 2179 |
+
component_buttons.append((btn, category))
|
| 2180 |
+
|
| 2181 |
+
if info.get('sub_components'):
|
| 2182 |
+
gr.Markdown("**Specialized:**")
|
| 2183 |
+
for sub_comp in info['sub_components']:
|
| 2184 |
+
if sub_comp in COMPONENT_INFO:
|
| 2185 |
+
sub_info = COMPONENT_INFO[sub_comp]
|
| 2186 |
+
sub_btn = gr.Button(
|
| 2187 |
+
f"{sub_info['icon']} {sub_comp.replace('_', ' ').title()}",
|
| 2188 |
+
size="sm"
|
| 2189 |
+
)
|
| 2190 |
+
component_buttons.append((sub_btn, sub_comp))
|
| 2191 |
+
|
| 2192 |
+
with gr.TabItem("All"):
|
| 2193 |
+
for comp_type, comp_info in COMPONENT_INFO.items():
|
| 2194 |
+
btn = gr.Button(
|
| 2195 |
+
f"{comp_info['icon']} {comp_type.replace('_', ' ').title()}",
|
| 2196 |
+
size="sm",
|
| 2197 |
+
variant="secondary"
|
| 2198 |
+
)
|
| 2199 |
+
component_buttons.append((btn, comp_type))
|
| 2200 |
+
|
| 2201 |
+
|
| 2202 |
+
gr.Markdown("---")
|
| 2203 |
+
example_dropdown = gr.Dropdown(
|
| 2204 |
+
choices=list(EXAMPLE_WORKFLOWS.keys()),
|
| 2205 |
+
label="Load Example",
|
| 2206 |
+
interactive=True
|
| 2207 |
+
)
|
| 2208 |
+
load_example_btn = gr.Button("π₯ Load", variant="secondary")
|
| 2209 |
+
|
| 2210 |
+
gr.Markdown("---")
|
| 2211 |
+
with gr.Row():
|
| 2212 |
+
clear_btn = gr.Button("ποΈ Clear", variant="stop")
|
| 2213 |
+
download_btn = gr.Button("πΎ Export", variant="primary")
|
| 2214 |
|
| 2215 |
# Center
|
| 2216 |
+
|
| 2217 |
+
|
| 2218 |
+
#================================================================================
|
| 2219 |
+
with gr.Column():
|
| 2220 |
+
# Config Modal -
|
| 2221 |
+
with gr.Column(visible=False, elem_classes=["modal-overlay"]) as config_modal:
|
| 2222 |
with gr.Row():
|
| 2223 |
+
gr.Markdown("") # Left spacer
|
| 2224 |
+
|
| 2225 |
+
# Modal content
|
| 2226 |
+
with gr.Column(scale=2, min_width=400, elem_classes=["modal-content"]):
|
| 2227 |
with gr.Row():
|
| 2228 |
+
config_modal_title = gr.Markdown("### βοΈ Configure Component")
|
| 2229 |
+
close_btn = gr.Button("β", size="sm", elem_classes=["close-btn"])
|
| 2230 |
|
| 2231 |
+
config_inputs = []
|
| 2232 |
+
for i in range(8): # Reasonable number of fields
|
| 2233 |
+
config_input = gr.Textbox(
|
| 2234 |
+
label=f"Field {i}",
|
| 2235 |
+
visible=False,
|
| 2236 |
+
interactive=True
|
| 2237 |
+
)
|
| 2238 |
+
config_inputs.append(config_input)
|
| 2239 |
|
| 2240 |
+
with gr.Row():
|
| 2241 |
+
save_new_btn = gr.Button("β
Add Component", variant="primary")
|
| 2242 |
+
save_edit_btn = gr.Button("β
Save Changes", variant="primary", visible=False)
|
| 2243 |
+
cancel_btn = gr.Button("β Cancel", variant="secondary")
|
| 2244 |
|
| 2245 |
+
gr.Markdown("") # Right spacer
|
|
|
|
|
|
|
| 2246 |
|
| 2247 |
+
#================================================================================
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2248 |
|
| 2249 |
+
# Canvas -
|
| 2250 |
+
with gr.Column(scale=3,min_width=600):
|
| 2251 |
+
gr.Markdown("## π¨ Canvas")
|
| 2252 |
+
canvas = gr.HTML(min_height=600,label="Workflow")
|
| 2253 |
+
|
| 2254 |
with gr.Row():
|
| 2255 |
+
with gr.Column(scale=2):
|
| 2256 |
+
gr.Markdown("### π― Selected")
|
| 2257 |
+
selected_node_info = gr.Markdown("No node selected")
|
|
|
|
| 2258 |
with gr.Row():
|
| 2259 |
+
from_node = gr.Dropdown(label="From", choices=[], interactive=True)
|
| 2260 |
+
to_node = gr.Dropdown(label="To", choices=[], interactive=True)
|
| 2261 |
+
connect_btn = gr.Button("β‘οΈ Connect", variant="secondary")
|
| 2262 |
+
|
| 2263 |
+
|
| 2264 |
+
with gr.Row():
|
| 2265 |
+
select_prev_btn = gr.Button("β¬
οΈ", size="sm")
|
| 2266 |
+
select_next_btn = gr.Button("β‘οΈ", size="sm")
|
|
|
|
|
|
|
|
|
|
| 2267 |
|
| 2268 |
+
gr.Markdown("**Move:**")
|
| 2269 |
with gr.Row():
|
| 2270 |
+
move_left_btn = gr.Button("β¬
οΈ", size="sm")
|
| 2271 |
+
move_up_btn = gr.Button("β¬οΈ", size="sm")
|
| 2272 |
+
move_down_btn = gr.Button("β¬οΈ", size="sm")
|
| 2273 |
+
move_right_btn = gr.Button("β‘οΈ", size="sm")
|
| 2274 |
+
|
| 2275 |
+
|
| 2276 |
+
delete_btn = gr.Button("ποΈ Delete", variant="stop", size="sm")
|
| 2277 |
+
edit_config_btn = gr.Button("βοΈ Config", variant="primary", size="sm")
|
| 2278 |
+
|
| 2279 |
+
with gr.Column(scale=1):
|
| 2280 |
+
gr.Markdown("### βοΈ Configuration")
|
| 2281 |
+
config_display = gr.JSON(label="Current Config")
|
| 2282 |
+
gr.Markdown("---")
|
| 2283 |
+
with gr.Row():
|
| 2284 |
+
gr.Markdown("---")
|
| 2285 |
+
gr.Markdown("## π Connections")
|
| 2286 |
+
|
| 2287 |
+
|
| 2288 |
+
#================================================================================
|
| 2289 |
+
|
| 2290 |
+
|
| 2291 |
+
|
| 2292 |
|
| 2293 |
+
|
| 2294 |
+
|
| 2295 |
+
# Right Sidebar
|
| 2296 |
+
with gr.Sidebar(width=600,position = "left",open = False):
|
| 2297 |
+
gr.Markdown("## π Info")
|
| 2298 |
+
|
| 2299 |
+
with gr.Accordion("π JSON", open=True):
|
| 2300 |
+
workflow_json = gr.JSON(label="Workflow Data")
|
| 2301 |
+
|
| 2302 |
+
with gr.Accordion("π Component", open=True):
|
| 2303 |
+
component_info = gr.Markdown("Select a component")
|
| 2304 |
+
|
| 2305 |
+
gr.Markdown("---")
|
| 2306 |
+
gr.Markdown("## π Report")
|
| 2307 |
+
report_btn = gr.Button("π Generate", variant="primary")
|
| 2308 |
+
report_output = gr.Textbox(label="Report", lines=10, interactive=False)
|
| 2309 |
+
|
| 2310 |
+
gr.Markdown("---")
|
| 2311 |
+
download_files = gr.Files(label="π₯ Downloads")
|
| 2312 |
+
#================================================================================
|
| 2313 |
# Add custom CSS for modal styling
|
| 2314 |
demo.css = """
|
| 2315 |
.modal-overlay {
|
|
|
|
| 2338 |
margin-bottom: 10px !important;
|
| 2339 |
}
|
| 2340 |
"""
|
| 2341 |
+
#================================================================================
|
| 2342 |
# Helper functions
|
| 2343 |
def get_full_state():
|
| 2344 |
svg = workflow.render_svg()
|
|
|
|
| 2456 |
def close_modal():
|
| 2457 |
"""Close modal and reset state"""
|
| 2458 |
return [gr.update(visible=False), "", ""]
|
| 2459 |
+
#================================================================================
|
| 2460 |
# Connect component buttons
|
| 2461 |
for btn, comp_type in component_buttons:
|
| 2462 |
btn.click(
|
|
|
|
| 2488 |
# Close modal actions
|
| 2489 |
cancel_btn.click(close_modal, outputs=[config_modal, pending_component_type, editing_node_id])
|
| 2490 |
close_btn.click(close_modal, outputs=[config_modal, pending_component_type, editing_node_id])
|
| 2491 |
+
#================================================================================
|
| 2492 |
# Navigation and other interactions remain the same...
|
| 2493 |
def navigate(direction):
|
| 2494 |
if workflow.nodes:
|
|
|
|
| 2508 |
for btn, dx, dy in [(move_left_btn, -20, 0), (move_right_btn, 20, 0), (move_up_btn, 0, -20), (move_down_btn, 0, 20)]:
|
| 2509 |
btn.click(lambda dx=dx, dy=dy: (workflow.move_selected_node(dx, dy) or get_full_state()),
|
| 2510 |
outputs=[canvas, from_node, to_node, selected_node_info, config_display, workflow_json, component_info])
|
| 2511 |
+
#================================================================================
|
| 2512 |
# Other actions
|
| 2513 |
connect_btn.click(lambda f, t: (workflow.add_connection(f, t) or get_full_state()) if f and t else get_full_state(),
|
| 2514 |
inputs=[from_node, to_node], outputs=[canvas, from_node, to_node, selected_node_info, config_display, workflow_json, component_info])
|
|
|
|
| 2521 |
|
| 2522 |
clear_btn.click(lambda: (workflow.nodes.clear(), workflow.connections.clear(), setattr(workflow, 'node_counter', 0), setattr(workflow, 'selected_node', None), get_full_state())[-1],
|
| 2523 |
outputs=[canvas, from_node, to_node, selected_node_info, config_display, workflow_json, component_info])
|
| 2524 |
+
#================================================================================
|
| 2525 |
# Export
|
| 2526 |
def export():
|
| 2527 |
wf = workflow.get_workflow_json()
|
|
|
|
| 2531 |
|
| 2532 |
svg_path = tempfile.mktemp(suffix="_workflow.svg")
|
| 2533 |
with open(svg_path, "w") as f:
|
| 2534 |
+
try:
|
| 2535 |
+
f.write(workflow.render_svg())
|
| 2536 |
+
except:
|
| 2537 |
+
pass
|
| 2538 |
return [json_path, svg_path]
|
| 2539 |
|
| 2540 |
download_btn.click(export, outputs=[download_files])
|
|
|
|
| 2547 |
return f"Error: {str(e)}\n\nEnsure LM Studio is running."
|
| 2548 |
|
| 2549 |
report_btn.click(gen_report, outputs=[report_output])
|
| 2550 |
+
#================================================================================
|
| 2551 |
# Initialize
|
| 2552 |
demo.load(get_full_state, outputs=[canvas, from_node, to_node, selected_node_info, config_display, workflow_json, component_info])
|
| 2553 |
|