vasanthfeb13 commited on
Commit
9422bc2
Β·
1 Parent(s): d802f0c

Add LinkedIn post link to UI Help section

Browse files
Files changed (1) hide show
  1. src/nacc_ui/professional_ui_v2.py +58 -186
src/nacc_ui/professional_ui_v2.py CHANGED
@@ -112,15 +112,15 @@ class ModernNACCUI(NACCConversationUI):
112
  dashboard = self.get_dashboard_view(session)
113
  files = self.list_files_view(session.current_path, session.current_node)
114
 
115
- return history, "", dashboard, files, session_id
116
 
117
  def get_dashboard_view(self, session: Optional[SessionState] = None) -> str:
118
  """Get real-time network dashboard with current node highlighted"""
119
  # Use default values if no session
120
- current_node = session.current_node if session else "hf-space-local"
121
  current_path = session.current_path if session else get_nacc_workspace()
122
  try:
123
- response = requests.get(f"{ORCHESTRATOR_URL}/nodes", timeout=15)
124
  if response.status_code == 200:
125
  nodes = response.json()
126
 
@@ -157,29 +157,27 @@ class ModernNACCUI(NACCConversationUI):
157
  except Exception as e:
158
  return f"❌ Dashboard Error: {str(e)}"
159
 
160
- def list_files_view(self, path: str = None, node: str = "hf-space-local") -> str:
161
  """List files in current directory on specified node"""
162
  # path and node should always be provided from session context
163
  # No fallback to avoid breaking context switching
164
 
165
  try:
166
- # Get node display name dynamically
167
- try:
168
- node_info = requests.get(f"{ORCHESTRATOR_URL}/nodes/{node}", timeout=5).json()
169
- node_label = node_info.get('display_name', node)
170
- except:
171
- node_label = node
172
 
173
- # Use orchestrator's execute command endpoint WITH node_id
174
  response = requests.post(
175
  f"{ORCHESTRATOR_URL}/commands/execute",
176
  json={
177
  "description": f"List files in {path} on {node}",
178
  "command": ["ls", "-lah", path],
179
- "node_id": node, # Direct node routing!
180
- "timeout": 10.0
 
181
  },
182
- timeout=12
183
  )
184
 
185
  if response.status_code == 200:
@@ -208,42 +206,16 @@ class ModernNACCUI(NACCConversationUI):
208
 
209
  def get_available_backends(self) -> Tuple[List[str], str]:
210
  """Fetch available backends from orchestrator"""
211
- try:
212
- response = requests.get(f"{ORCHESTRATOR_URL}/backends/available", timeout=5)
213
- if response.status_code == 200:
214
- data = response.json()
215
- backends = data.get("backends", [])
216
- choices = []
217
- info = "**πŸ€– Available AI Backends:**\n\n"
218
-
219
- for backend in backends:
220
- name = backend["name"]
221
- display = backend["display_name"]
222
- model = backend.get("model", "N/A")
223
- is_free = backend["is_free"]
224
- requires_key = backend["requires_api_key"]
225
-
226
- # Format: "modal - Modal A100 FREE (IBM Granite MoE)"
227
- label = f"{name} - {display}"
228
- if is_free:
229
- label += " πŸ†“"
230
- if requires_key:
231
- label += " πŸ”‘"
232
-
233
- choices.append((label, name))
234
-
235
- # Add to info
236
- status = "πŸ†“ FREE" if is_free else "πŸ’³ Paid"
237
- key_status = "πŸ”‘ API Key Required" if requires_key else "✨ No Key"
238
- info += f"**{display}** ({status}, {key_status})\n"
239
- info += f" β€’ Model: {model}\n"
240
- info += f" β€’ Description: {backend['description']}\n\n"
241
-
242
- return choices, info
243
- else:
244
- return [("modal", "modal")], "⚠️ Failed to load backends"
245
- except Exception as e:
246
- return [("modal", "modal")], f"❌ Error: {str(e)}"
247
 
248
  def get_backend_status(self) -> str:
249
  """Get current backend status"""
@@ -309,10 +281,10 @@ class ModernNACCUI(NACCConversationUI):
309
  """Execute comprehensive health checks"""
310
  try:
311
  # Get orchestrator health
312
- health_response = requests.get(f"{ORCHESTRATOR_URL}/healthz", timeout=15)
313
 
314
  # Get nodes status
315
- nodes_response = requests.get(f"{ORCHESTRATOR_URL}/nodes", timeout=15)
316
 
317
  result = """βœ… **Health Check Results**
318
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
@@ -489,7 +461,7 @@ def create_professional_ui_v2():
489
  demo.title = "NACC Enterprise AI"
490
 
491
  # Session state
492
- session_id = gr.State(value=hashlib.md5(str(datetime.now().timestamp()).encode()).hexdigest()[:8])
493
 
494
  # Main Layout: VS Code Style (Left Sidebar | Main Chat)
495
  with gr.Row(elem_id="main-container", variant="panel", equal_height=True):
@@ -557,7 +529,8 @@ def create_professional_ui_v2():
557
  height=600,
558
  show_label=False,
559
  avatar_images=(None, "πŸ€–"),
560
- elem_id="main-chatbot"
 
561
  )
562
 
563
  # Input Area
@@ -577,7 +550,7 @@ def create_professional_ui_v2():
577
  """
578
  <div style="display: flex; justify-content: space-between; font-size: 0.8em; color: #64748b; margin-top: 5px; margin-bottom: 20px;">
579
  <span>⚠️ Blaxel Sandbox: 30-70s processing</span>
580
- <span>Context: hf-space-local</span>
581
  </div>
582
  """
583
  )
@@ -591,142 +564,41 @@ def create_professional_ui_v2():
591
  # Bottom Section: Help & About (Full Width)
592
  with gr.Row(elem_id="bottom-section"):
593
  with gr.Column(scale=1):
594
- with gr.Accordion("πŸ“š Demo Guide & Instructions", open=False):
595
  gr.Markdown("""
596
- # 🎯 HuggingFace Space Demo Guide
597
-
598
- ## Step-by-Step Demo Instructions
599
-
600
- ### Step 1: List Available Nodes
601
- ```
602
- list nodes
603
- ```
604
- You'll see two nodes:
605
- - `vm-node-01` - VM Space (remote computer simulation)
606
- - `hf-space-local` - Main Space (this project, blocked for protection)
607
-
608
- ### Step 2: Switch to VM Node
609
- ```
610
- switch to vm-node-01
611
- ```
612
- Path will automatically set to `/app` (VM's root directory)
613
-
614
- ### Step 3: Explore VM Files
615
- ```
616
- list files
617
- ```
618
- Navigate through folders using **absolute paths**:
619
- ```
620
- navigate to /app/src
621
- navigate to /app/src/nacc_ui
622
- navigate to /app
623
- ```
624
-
625
- ### Step 4: File Operations in /tmp
626
- ⚠️ **IMPORTANT**: File creation only works in `/tmp/` directory
627
-
628
- ```
629
- navigate to /tmp
630
- ```
631
-
632
- **Create a file (AI-powered)**:
633
- ```
634
- create a file named demo.txt with content Hello from NACC!
635
- ```
636
-
637
- **Read the file**:
638
- ```
639
- run command cat /tmp/demo.txt
640
- ```
641
-
642
- **List to verify**:
643
- ```
644
- list files
645
- ```
646
-
647
- ---
648
-
649
- ## ⚠️ Important Limitations
650
-
651
- **Write Operations**:
652
- - βœ… Work in: `/tmp/` directory (writable)
653
- - ❌ Blocked in: `/app/` and other areas (read-only to protect project)
654
 
655
- **Why?** This protects the running application code from accidental modification.
656
 
657
  ---
658
 
659
- ## πŸ† For Judges
660
-
661
- ### Project Background
662
- **Built from scratch** - No pre-made MCPs or templates used. Every line of code was written specifically for this project.
663
-
664
- ### Original Design
665
- NACC was designed for **real computers on the same network**:
666
- - Control multiple PCs/servers/VMs via MCP
667
- - Full file operations (read, write, create, share, edit)
668
- - Network-wide orchestration with AI
669
-
670
- ### Space Adaptation Challenge
671
- To submit this project to Hugging Face Spaces, I created a unique approach:
672
-
673
- 1. **VM Space** (`NACC-VM`) - Acts as a remote node/computer
674
- 2. **Main Space** (this one) - Acts as the orchestrator + local node
675
- 3. **HTTP Communication** - Simulates network communication between computers
676
-
677
- **Trade-offs Made**:
678
- - Blocked operations on `hf-space-local` (protects core project)
679
- - Limited file operations to `/tmp` on VM (safety)
680
- - Real NACC has full system access, Space version is restricted
681
-
682
- ### What NACC Really Does
683
- In a real deployment (see demo video):
684
- - Controls entire networks of computers
685
- - Full filesystem access across all nodes
686
- - File sharing between any nodes
687
- - System monitoring and management
688
- - AI-powered multi-node orchestration
689
-
690
- **Demo Videos**: Shows both Space demo AND real NACC setup
691
-
692
- ---
693
-
694
- ## πŸ’¬ To The Community
695
-
696
- Thank you for checking out NACC! This entire project was built from zero - no pre-made MCPs, no templates, all original code.
697
-
698
- ### About Me
699
- I'm **Vasanthadithya** - 3rd year B.E. Computer Science student at **CBIT, Hyderabad**
700
-
701
- ### Looking For
702
- - 🎯 Internship opportunities
703
- - 🀝 Experience and learning
704
- - πŸš€ Chance to work on real-world projects
705
-
706
- If you like this project and its approach, I'd love to connect! I want to learn, explore, and build amazing things.
707
-
708
- πŸ“§ **Reach out**: [LinkedIn](https://www.linkedin.com/in/vasanthadithya-mundrathi-84a54031a/) | [GitHub](https://github.com/Vasanthadithya-mundrathi)
709
-
710
- ---
711
-
712
- ## πŸ€— Competition Tags
713
-
714
- **PRIMARY TRACKS:**
715
- - 🏒 `mcp-in-action-track-enterprise` - Multi-node infrastructure orchestration
716
- - πŸ‘€ `mcp-in-action-track-consumer` - Natural language control
717
- - 🎨 `mcp-in-action-track-creative` - Novel cross-Space architecture
718
-
719
- **SECONDARY TRACKS:**
720
- - πŸ› οΈ `building-mcp-track-enterprise` - Complete MCP implementation
721
- - πŸ› οΈ `building-mcp-track-consumer` - Custom protocol from scratch
722
- - πŸ› οΈ `building-mcp-track-creative` - Zero SDK dependencies
723
-
724
- ---
725
-
726
- ## πŸ€– AI Backend
727
- **Current**: Blaxel OpenAI (GPT-4o-mini) - Powers natural language understanding
728
-
729
- Built with ❀️ for **HF MCP Birthday Hackathon 2025** πŸŽ‚
730
  """)
731
 
732
  with gr.Accordion("πŸ‘¨β€πŸ’» About Creator & NACC", open=False):
 
112
  dashboard = self.get_dashboard_view(session)
113
  files = self.list_files_view(session.current_path, session.current_node)
114
 
115
+ return history, "", dashboard, files, session.session_id
116
 
117
  def get_dashboard_view(self, session: Optional[SessionState] = None) -> str:
118
  """Get real-time network dashboard with current node highlighted"""
119
  # Use default values if no session
120
+ current_node = session.current_node if session else "macbook-local"
121
  current_path = session.current_path if session else get_nacc_workspace()
122
  try:
123
+ response = requests.get(f"{ORCHESTRATOR_URL}/nodes", timeout=5)
124
  if response.status_code == 200:
125
  nodes = response.json()
126
 
 
157
  except Exception as e:
158
  return f"❌ Dashboard Error: {str(e)}"
159
 
160
+ def list_files_view(self, path: str = None, node: str = "macbook-local") -> str:
161
  """List files in current directory on specified node"""
162
  # path and node should always be provided from session context
163
  # No fallback to avoid breaking context switching
164
 
165
  try:
166
+ # Determine preferred tags based on node
167
+ preferred_tags = ["mac", "local"] if node == "macbook-local" else ["kali", "vm"]
168
+ node_label = "MacBook Pro" if node == "macbook-local" else "Kali VM"
 
 
 
169
 
170
+ # Use orchestrator's execute command endpoint
171
  response = requests.post(
172
  f"{ORCHESTRATOR_URL}/commands/execute",
173
  json={
174
  "description": f"List files in {path} on {node}",
175
  "command": ["ls", "-lah", path],
176
+ "preferred_tags": preferred_tags,
177
+ "target_node": node,
178
+ "timeout": 30
179
  },
180
+ timeout=60 # Increased from 15s to 60s
181
  )
182
 
183
  if response.status_code == 200:
 
206
 
207
  def get_available_backends(self) -> Tuple[List[str], str]:
208
  """Fetch available backends from orchestrator"""
209
+ # Hardcoded for now since orchestrator doesn't support dynamic switching yet
210
+ choices = [("Blaxel Sandbox πŸš€", "blaxel-openai")]
211
+ info = """**πŸ€– Active Backend:**
212
+
213
+ **Blaxel Sandbox** (vasanthfeb13)
214
+ β€’ Model: sandbox-openai
215
+ β€’ Status: βœ… Active
216
+ β€’ Provider: Blaxel Model Gateway
217
+ """
218
+ return choices, info
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
219
 
220
  def get_backend_status(self) -> str:
221
  """Get current backend status"""
 
281
  """Execute comprehensive health checks"""
282
  try:
283
  # Get orchestrator health
284
+ health_response = requests.get(f"{ORCHESTRATOR_URL}/healthz", timeout=5)
285
 
286
  # Get nodes status
287
+ nodes_response = requests.get(f"{ORCHESTRATOR_URL}/nodes", timeout=5)
288
 
289
  result = """βœ… **Health Check Results**
290
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 
461
  demo.title = "NACC Enterprise AI"
462
 
463
  # Session state
464
+ session_id = gr.State()
465
 
466
  # Main Layout: VS Code Style (Left Sidebar | Main Chat)
467
  with gr.Row(elem_id="main-container", variant="panel", equal_height=True):
 
529
  height=600,
530
  show_label=False,
531
  avatar_images=(None, "πŸ€–"),
532
+ elem_id="main-chatbot",
533
+ type="messages"
534
  )
535
 
536
  # Input Area
 
550
  """
551
  <div style="display: flex; justify-content: space-between; font-size: 0.8em; color: #64748b; margin-top: 5px; margin-bottom: 20px;">
552
  <span>⚠️ Blaxel Sandbox: 30-70s processing</span>
553
+ <span>Context: macbook-local</span>
554
  </div>
555
  """
556
  )
 
564
  # Bottom Section: Help & About (Full Width)
565
  with gr.Row(elem_id="bottom-section"):
566
  with gr.Column(scale=1):
567
+ with gr.Accordion("πŸ“š Help & Documentation", open=False):
568
  gr.Markdown("""
569
+ ### πŸ“’ **Latest Updates**
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
570
 
571
+ **[πŸš€ Read the Official Launch Post on LinkedIn](https://www.linkedin.com/posts/vasanthadithya-mundrathi-84a54031a_mcp-modelcontextprotocol-mcpbirthday-activity-7400561851106897920-0i1u?utm_source=share&utm_medium=member_desktop&rcm=ACoAAFDhpLoBNcrQ4qiK_sGt54NWi9Zd-0VanIM)**
572
 
573
  ---
574
 
575
+ ### 🎯 Quick Start Guide
576
+
577
+ **1. File Operations**
578
+ * `list files` - See what's in your current directory.
579
+ * `read [filename]` - View the contents of a file.
580
+ * `write [content] to [filename]` - Create or update a file.
581
+
582
+ **2. Node Management** ⭐ *NEW FEATURES*
583
+ * `list nodes` - See all connected machines.
584
+ * `switch to [node-id]` - Switch by exact node ID (e.g., `switch to kali-vm`, `switch to macbook-local`).
585
+ * `switch to [alias]` - Use aliases (e.g., `switch to kali`, `switch to mac`, `switch to laptop`).
586
+ * **Connect New Nodes**: `connect to [6-digit-code] at [ip-address] and name it as [name]`
587
+ - Example: `connect to 473293 at 192.168.1.50 and name it as my-laptop`
588
+ - First run `nacc-node init` on the remote node to get the pairing code!
589
+
590
+ **3. System Monitoring**
591
+ * `show system metrics` - View CPU, RAM, and Disk usage.
592
+ * `check disk space` - Quick storage check.
593
+
594
+ **4. AI Backends (Top Right Settings)**
595
+ * **Blaxel Sandbox**: βœ… Default. Free, reliable, ~30-70s response time.
596
+ * **Docker Mistral**: Runs locally on your machine. Fast & Free.
597
+ * **OpenAI/Gemini**: Requires your own API key for max speed.
598
+
599
+ ### πŸ’‘ Tips
600
+ - Context is preserved! After switching nodes, all file operations use that node's path.
601
+ - You can switch nodes by ID, display name, or alias - whatever you remember!
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
602
  """)
603
 
604
  with gr.Accordion("πŸ‘¨β€πŸ’» About Creator & NACC", open=False):