LeroyDyer commited on
Commit
109dec0
Β·
verified Β·
1 Parent(s): e14b078

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +322 -315
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
- ## UML TOOLOX !
15
- # Unified Hierarchical Component definitions for UML and Object-Oriented Design
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
- gr.Markdown("---")
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
- with gr.Row(equal_height=False):
2177
- # Left Sidebar
2178
- with gr.Column(scale=1, min_width=300):
2179
- gr.Markdown("## πŸ“š Component Library")
2180
-
2181
- with gr.Tabs():
2182
- with gr.TabItem("Categories"):
2183
- component_buttons = []
2184
- for category, info in COMPONENT_HIERARCHY["HIGH_LEVEL"].items():
2185
- with gr.Accordion(f"{info['icon']} {category}", open=False):
2186
- gr.Markdown(f"*{info['description']}*")
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"{comp_info['icon']} {comp_type.replace('_', ' ').title()}",
2210
  size="sm",
2211
- variant="secondary"
2212
  )
2213
- component_buttons.append((btn, comp_type))
2214
-
2215
- gr.Markdown("---")
2216
- gr.Markdown("## πŸ”— Connections")
2217
- with gr.Row():
2218
- from_node = gr.Dropdown(label="From", choices=[], interactive=True)
2219
- to_node = gr.Dropdown(label="To", choices=[], interactive=True)
2220
- connect_btn = gr.Button("➑️ Connect", variant="secondary")
2221
-
2222
- gr.Markdown("---")
2223
- example_dropdown = gr.Dropdown(
2224
- choices=list(EXAMPLE_WORKFLOWS.keys()),
2225
- label="Load Example",
2226
- interactive=True
2227
- )
2228
- load_example_btn = gr.Button("πŸ“₯ Load", variant="secondary")
2229
-
2230
- gr.Markdown("---")
2231
- with gr.Row():
2232
- clear_btn = gr.Button("πŸ—‘οΈ Clear", variant="stop")
2233
- download_btn = gr.Button("πŸ’Ύ Export", variant="primary")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2234
 
2235
  # Center
2236
- with gr.Column(scale=3):
2237
- gr.Markdown("## 🎨 Canvas")
2238
- canvas = gr.HTML(label="Workflow")
2239
-
 
 
2240
  with gr.Row():
2241
- with gr.Column(scale=1):
2242
- gr.Markdown("### 🎯 Selected")
2243
- selected_node_info = gr.Markdown("No node selected")
2244
-
2245
  with gr.Row():
2246
- select_prev_btn = gr.Button("⬅️", size="sm")
2247
- select_next_btn = gr.Button("➑️", size="sm")
2248
 
2249
- gr.Markdown("**Move:**")
2250
- with gr.Row():
2251
- move_left_btn = gr.Button("⬅️", size="sm")
2252
- move_up_btn = gr.Button("⬆️", size="sm")
2253
- move_down_btn = gr.Button("⬇️", size="sm")
2254
- move_right_btn = gr.Button("➑️", size="sm")
 
 
2255
 
2256
- delete_btn = gr.Button("πŸ—‘οΈ Delete", variant="stop", size="sm")
2257
- edit_config_btn = gr.Button("βš™οΈ Config", variant="primary", size="sm")
 
 
2258
 
2259
- with gr.Column(scale=2):
2260
- gr.Markdown("### βš™οΈ Configuration")
2261
- config_display = gr.JSON(label="Current Config")
2262
 
2263
- # Right Sidebar
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
- # Config Modal - FIXED: Proper modal implementation
2282
- with gr.Column(visible=False, elem_classes=["modal-overlay"]) as config_modal:
 
 
 
2283
  with gr.Row():
2284
- gr.Markdown("") # Left spacer
2285
-
2286
- # Modal content
2287
- with gr.Column(scale=2, min_width=400, elem_classes=["modal-content"]):
2288
  with gr.Row():
2289
- config_modal_title = gr.Markdown("### βš™οΈ Configure Component")
2290
- close_btn = gr.Button("❌", size="sm", elem_classes=["close-btn"])
2291
-
2292
- config_inputs = []
2293
- for i in range(8): # Reasonable number of fields
2294
- config_input = gr.Textbox(
2295
- label=f"Field {i}",
2296
- visible=False,
2297
- interactive=True
2298
- )
2299
- config_inputs.append(config_input)
2300
 
 
2301
  with gr.Row():
2302
- save_new_btn = gr.Button("βœ… Add Component", variant="primary")
2303
- save_edit_btn = gr.Button("βœ… Save Changes", variant="primary", visible=False)
2304
- cancel_btn = gr.Button("❌ Cancel", variant="secondary")
2305
-
2306
- gr.Markdown("") # Right spacer
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
- f.write(workflow.render_svg())
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