diff --git a/agent_chat/autonomous_planner.py b/agent_chat/autonomous_planner.py index 3f47e1222..7edbf4629 100644 --- a/agent_chat/autonomous_planner.py +++ b/agent_chat/autonomous_planner.py @@ -49,7 +49,10 @@ try: from PIL import Image as PILImage import pyautogui PYAUTOGUI_AVAILABLE = True -except ImportError: +except Exception: + # pyautogui peut lever Xlib.error.DisplayConnectionError (pas un ImportError) + # quand X n'est pas accessible — typique d'un service systemd headless côté + # serveur. Le serveur n'a pas besoin de pyautogui (utilisé côté client agent). PYAUTOGUI_AVAILABLE = False PILImage = None pyautogui = None diff --git a/core/execution/input_handler.py b/core/execution/input_handler.py index 273290020..30ffdcaa1 100644 --- a/core/execution/input_handler.py +++ b/core/execution/input_handler.py @@ -19,7 +19,9 @@ logger = logging.getLogger(__name__) try: import pyautogui PYAUTOGUI_AVAILABLE = True -except ImportError: +except Exception: + # pyautogui peut lever Xlib.error.DisplayConnectionError (pas un ImportError) + # quand X n'est pas accessible — typique d'un service systemd côté serveur. PYAUTOGUI_AVAILABLE = False try: diff --git a/core/execution/observe_reason_act.py b/core/execution/observe_reason_act.py index 567f2b4e4..0ab5d59a9 100644 --- a/core/execution/observe_reason_act.py +++ b/core/execution/observe_reason_act.py @@ -58,7 +58,9 @@ except ImportError: try: import pyautogui PYAUTOGUI_AVAILABLE = True -except ImportError: +except Exception: + # pyautogui peut lever Xlib.error.DisplayConnectionError ou KeyError('DISPLAY') + # quand X n'est pas accessible — typique d'un service systemd côté serveur. pyautogui = None PYAUTOGUI_AVAILABLE = False diff --git a/deploy/systemd/rpa-streaming.service b/deploy/systemd/rpa-streaming.service index 4d6610a7d..8bbe93e6d 100644 --- a/deploy/systemd/rpa-streaming.service +++ b/deploy/systemd/rpa-streaming.service @@ -14,6 +14,9 @@ WorkingDirectory=/home/dom/ai/rpa_vision_v3 EnvironmentFile=/home/dom/ai/rpa_vision_v3/.env.local Environment="PYTHONUNBUFFERED=1" Environment="RPA_SERVICE_NAME=rpa-streaming" +# Service grounding persistant — socket + répertoire d'images partagés via /run/rpa/. +Environment="RPA_GROUNDING_SOCKET=/run/rpa/grounding.sock" +Environment="RPA_GROUNDING_IMG_DIR=/run/rpa" # Lancement via le module Python (même commande que svc.sh) ExecStart=/home/dom/ai/rpa_vision_v3/.venv/bin/python3 -m agent_v0.server_v1.api_stream @@ -29,6 +32,10 @@ KillSignal=SIGTERM # ---- Hardening (raisonnable pour un poste de dev/prod) ---- NoNewPrivileges=true PrivateTmp=true +# /run/rpa/ partagé avec rpa-grounding (socket + images) +RuntimeDirectory=rpa +RuntimeDirectoryMode=0755 +RuntimeDirectoryPreserve=yes # Logs -> journald StandardOutput=journal diff --git a/deploy/systemd/rpa-vision-v3-api.service b/deploy/systemd/rpa-vision-v3-api.service index 6b1512d92..ff4a842cd 100644 --- a/deploy/systemd/rpa-vision-v3-api.service +++ b/deploy/systemd/rpa-vision-v3-api.service @@ -14,6 +14,11 @@ EnvironmentFile=/home/dom/ai/rpa_vision_v3/.env.local Environment="PYTHONUNBUFFERED=1" Environment="ENVIRONMENT=production" Environment="RPA_SERVICE_NAME=rpa-vision-v3-api" +# Service grounding persistant — socket + répertoire d'images partagés via /run/rpa/. +# Si le service rpa-grounding n'est pas démarré, le client retombe automatiquement +# sur le subprocess one-shot (cf. ui_tars_grounder.py). +Environment="RPA_GROUNDING_SOCKET=/run/rpa/grounding.sock" +Environment="RPA_GROUNDING_IMG_DIR=/run/rpa" ExecStart=/home/dom/ai/rpa_vision_v3/.venv/bin/python3 server/api_upload.py @@ -25,6 +30,11 @@ TimeoutStopSec=30 # ---- Hardening ---- NoNewPrivileges=true PrivateTmp=true +# /run/rpa/ partagé avec rpa-grounding pour le socket et les images grounding. +# Le service rpa-grounding crée le répertoire ; ici on l'expose au /run du service. +RuntimeDirectory=rpa +RuntimeDirectoryMode=0755 +RuntimeDirectoryPreserve=yes # Logs -> journald StandardOutput=journal diff --git a/deploy/systemd/rpa-vision-v3-dashboard.service b/deploy/systemd/rpa-vision-v3-dashboard.service index c844eace1..9ca081547 100644 --- a/deploy/systemd/rpa-vision-v3-dashboard.service +++ b/deploy/systemd/rpa-vision-v3-dashboard.service @@ -12,6 +12,9 @@ EnvironmentFile=/home/dom/ai/rpa_vision_v3/.env.local Environment="PYTHONUNBUFFERED=1" Environment="ENVIRONMENT=production" Environment="RPA_SERVICE_NAME=rpa-vision-v3-dashboard" +# Service grounding persistant +Environment="RPA_GROUNDING_SOCKET=/run/rpa/grounding.sock" +Environment="RPA_GROUNDING_IMG_DIR=/run/rpa" ExecStart=/home/dom/ai/rpa_vision_v3/.venv/bin/python3 web_dashboard/app.py Restart=on-failure diff --git a/deploy/systemd/rpa-vision-v3-worker.service b/deploy/systemd/rpa-vision-v3-worker.service index b09545c3a..b186e46aa 100644 --- a/deploy/systemd/rpa-vision-v3-worker.service +++ b/deploy/systemd/rpa-vision-v3-worker.service @@ -10,6 +10,9 @@ Group=dom WorkingDirectory=/home/dom/ai/rpa_vision_v3 EnvironmentFile=/home/dom/ai/rpa_vision_v3/.env.local Environment="PYTHONUNBUFFERED=1" +# Service grounding persistant — socket + répertoire d'images partagés via /run/rpa/. +Environment="RPA_GROUNDING_SOCKET=/run/rpa/grounding.sock" +Environment="RPA_GROUNDING_IMG_DIR=/run/rpa" ExecStart=/home/dom/ai/rpa_vision_v3/.venv/bin/python3 server/worker_daemon.py Restart=on-failure @@ -18,6 +21,10 @@ TimeoutStopSec=60 NoNewPrivileges=true PrivateTmp=true +# /run/rpa/ partagé avec rpa-grounding (socket + images) +RuntimeDirectory=rpa +RuntimeDirectoryMode=0755 +RuntimeDirectoryPreserve=yes StandardOutput=journal StandardError=journal