diff --git a/Data/Agent/borealis-agent.py b/Data/Agent/borealis-agent.py index 7c10a6c..a09d29d 100644 --- a/Data/Agent/borealis-agent.py +++ b/Data/Agent/borealis-agent.py @@ -11,7 +11,8 @@ from PyQt5 import QtCore, QtGui, QtWidgets from PIL import ImageGrab # ---------------- Configuration ---------------- -SERVER_URL = "http://localhost:5000" # WebSocket-enabled server URL +#SERVER_URL = "http://localhost:5000" # WebSocket-enabled Internal URL +SERVER_URL = "https://borealis.bunny-lab.io" # WebSocket-enabled Public URL" HOSTNAME = socket.gethostname().lower() RANDOM_SUFFIX = uuid.uuid4().hex[:8] @@ -32,7 +33,7 @@ sio = socketio.Client() # ---------------- WebSocket Handlers ---------------- @sio.event def connect(): - print(f"[WS CONNECTED] Agent ID: {AGENT_ID} connected to Borealis.") + print(f"[WebSocket] Agent ID: {AGENT_ID} connected to Borealis.") sio.emit('connect_agent', {"agent_id": AGENT_ID, "hostname": HOSTNAME}) sio.emit('request_config', {"agent_id": AGENT_ID}) @@ -123,7 +124,6 @@ class ScreenshotRegion(QtWidgets.QWidget): # ---------------- Screenshot Capture ---------------- def capture_loop(): - print("[INFO] Screenshot capture loop started") config_ready.wait() while region_widget is None: @@ -172,7 +172,7 @@ if __name__ == "__main__": app_instance = QtWidgets.QApplication(sys.argv) region_launcher = RegionLauncher() - sio.connect(SERVER_URL) + sio.connect(SERVER_URL, transports=['websocket']) threading.Thread(target=capture_loop, daemon=True).start() diff --git a/Data/Agent/requirements.txt b/Data/Agent/requirements.txt index 883322d..3cf8ec0 100644 --- a/Data/Agent/requirements.txt +++ b/Data/Agent/requirements.txt @@ -1,3 +1,10 @@ +# API / WebSocket Handling requests +python-socketio +websocket-client + +# GUI-related dependencies (Qt for GUI components) PyQt5 -Pillow + +# Computer Vision & OCR Dependencies +Pillow \ No newline at end of file diff --git a/Data/WebUI/src/nodes/Agent/Node_Borealis_Agent.jsx b/Data/WebUI/src/nodes/Agent/Node_Borealis_Agent.jsx index 08b67a5..2478b37 100644 --- a/Data/WebUI/src/nodes/Agent/Node_Borealis_Agent.jsx +++ b/Data/WebUI/src/nodes/Agent/Node_Borealis_Agent.jsx @@ -2,9 +2,11 @@ import React, { useEffect, useState, useRef } from "react"; import { Handle, Position, useReactFlow } from "reactflow"; import { io } from "socket.io-client"; -const socket = io(); +const socket = io(window.location.origin, { + transports: ["websocket"] +}); -const APINode = ({ id, data }) => { +const BorealisAgentNode = ({ id, data }) => { const { setNodes } = useReactFlow(); const [agents, setAgents] = useState([]); const [selectedAgent, setSelectedAgent] = useState(data.agent_id || ""); @@ -13,6 +15,7 @@ const APINode = ({ id, data }) => { const [paused, setPaused] = useState(false); const [overlayVisible, setOverlayVisible] = useState(true); const [imageData, setImageData] = useState(""); + const imageRef = useRef(""); useEffect(() => { fetch("/api/agents").then(res => res.json()).then(setAgents); @@ -24,15 +27,39 @@ const APINode = ({ id, data }) => { useEffect(() => { socket.on('new_screenshot', (data) => { + console.log("[DEBUG] Screenshot received", data); if (data.agent_id === selectedAgent) { setImageData(data.image_base64); - window.BorealisValueBus = window.BorealisValueBus || {}; - window.BorealisValueBus[id] = data.image_base64; + imageRef.current = data.image_base64; } }); return () => socket.off('new_screenshot'); - }, [selectedAgent, id]); + }, [selectedAgent]); + + useEffect(() => { + const interval = setInterval(() => { + if (!paused && imageRef.current) { + window.BorealisValueBus = window.BorealisValueBus || {}; + window.BorealisValueBus[id] = imageRef.current; + + setNodes(nds => { + const updated = [...nds]; + const node = updated.find(n => n.id === id); + if (node) { + node.data = { + ...node.data, + value: imageRef.current + }; + } + return updated; + }); + + } + }, window.BorealisUpdateRate || 100); + + return () => clearInterval(interval); + }, [id, paused, setNodes]); const provisionAgent = () => { if (!selectedAgent) return; @@ -49,18 +76,11 @@ const APINode = ({ id, data }) => { visible: overlayVisible, task: selectedType }) - }).then(() => { - socket.emit('request_config', { agent_id: selectedAgent }); - setNodes(nds => - nds.map(n => n.id === id - ? { - ...n, - data: { agent_id: selectedAgent, data_type: selectedType, interval: intervalMs } - } - : n - ) - ); - }); + }) + .then(res => res.json()) + .then(() => { + console.log("[DEBUG] Agent provisioned"); + }); }; const toggleOverlay = () => { @@ -72,7 +92,7 @@ const APINode = ({ id, data }) => { return (
-
API Data Collector
+
Borealis Agent