feat: popup VLM double-appel, auth Bearer partout, texte AZERTY corrigé

- Popup handling via double appel VLM (détection + localisation précise du bouton)
- Reconstruction texte depuis raw_keys (numpad /, @ AltGr fusionné)
- Clipboard paste pour texte riche, raw_keys pour commandes simples (Win+R)
- Skip des release orphelins dans raw_keys (fix menu Démarrer parasite)
- Auth Bearer sur toutes les requêtes agent → streaming server
- Endpoints /replay/next et /stream/image publics (agent Rust legacy)
- alt_gr ajouté dans _MODIFIER_ONLY_KEYS
- _key_combo_printable_char détecte ctrl+@ comme caractère imprimable
- start.bat tue les anciens process (python + rpa-agent) au démarrage
- Heartbeat avec token Bearer dans main.py et deploy/

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dom
2026-03-30 16:45:09 +02:00
parent c2dc8f8fe4
commit 647aa610fd
10 changed files with 307 additions and 56 deletions

View File

@@ -16,7 +16,7 @@ import logging
import threading
from .config import (
SESSIONS_ROOT, AGENT_VERSION, SERVER_URL, MACHINE_ID, LOG_RETENTION_DAYS,
SCREEN_RESOLUTION, DPI_SCALE, OS_THEME,
SCREEN_RESOLUTION, DPI_SCALE, OS_THEME, API_TOKEN,
)
from .core.captor import EventCaptorV1
from .core.executor import ActionExecutorV1
@@ -77,7 +77,14 @@ class AgentV1:
# Client serveur pour le chat et les workflows
self._server_client = None
if LeaServerClient is not None:
self._server_client = LeaServerClient()
# Forcer le token API pour éviter les 401
# (le token est set par start.bat dans l'environnement)
from .config import API_TOKEN as _token
server_host = os.getenv("RPA_SERVER_HOST", "localhost")
self._server_client = LeaServerClient(server_host=server_host)
if _token and not self._server_client._api_token:
self._server_client._api_token = _token
logger.info("Token API forcé dans LeaServerClient")
# Fenetre de chat Lea (tkinter natif)
server_host = (
@@ -288,7 +295,8 @@ class AgentV1:
continue
self._last_bg_hash = img_hash
# Envoyer au streaming server
# Envoyer au streaming server (avec token auth)
headers = {"Authorization": f"Bearer {API_TOKEN}"} if API_TOKEN else {}
with open(full_path, 'rb') as f:
req.post(
f"{SERVER_URL}/traces/stream/image",
@@ -297,6 +305,7 @@ class AgentV1:
"shot_id": f"heartbeat_{int(time.time())}",
"machine_id": self.machine_id,
},
headers=headers,
files={"file": ("screenshot.png", f, "image/png")},
timeout=10,
)

View File

@@ -474,9 +474,14 @@ class SmartTrayV1:
try:
import requests
# Auth headers pour le streaming server (port 5005)
auth_headers = {}
if self.server_client is not None:
auth_headers = self.server_client._auth_headers()
resp = requests.post(
f"{self.server_client._stream_base}/api/v1/traces/stream/replay/start",
json={"workflow_id": workflow_id},
headers=auth_headers,
timeout=10,
)
if resp.ok: