fix: corrections audit qualité — stop/pause ORA + nettoyage debug
Some checks failed
security-audit / Bandit (scan statique) (push) Successful in 12s
security-audit / pip-audit (CVE dépendances) (push) Successful in 10s
security-audit / Scan secrets (grep) (push) Successful in 8s
tests / Lint (ruff + black) (push) Successful in 16s
tests / Tests unitaires (sans GPU) (push) Failing after 14s
tests / Tests sécurité (critique) (push) Has been skipped

CRITIQUE : ajout should_continue callback dans ORALoop pour supporter
les boutons Stop/Pause du frontend en mode verified et instruction.

HAUTE : suppression sys.stdout.write de debug, logger.warning→debug
dans _grounding_ocr.

BASSE : suppression import mort 'field' dans observe_reason_act.py.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dom
2026-04-22 11:17:20 +02:00
parent 00134963e5
commit 9d87ed64c5
3 changed files with 19 additions and 5 deletions

View File

@@ -450,8 +450,7 @@ def _grounding_ocr(target_text: str, anchor_bbox: Optional[Dict] = None) -> Opti
- Si anchor_bbox fourni → le plus proche de la position originale - Si anchor_bbox fourni → le plus proche de la position originale
- Sinon → le plus proche du centre de l'écran (zone contenu) - Sinon → le plus proche du centre de l'écran (zone contenu)
""" """
logger.warning(f"[OCR-V2] Entrée _grounding_ocr target='{target_text}' bbox={anchor_bbox}") logger.debug(f"[Grounding/OCR] target='{target_text}' bbox={anchor_bbox}")
import sys; sys.stdout.write(f" [OCR-V2] target='{target_text}' bbox={anchor_bbox}\n"); sys.stdout.flush()
if not target_text: if not target_text:
return None return None

View File

@@ -17,7 +17,7 @@ import base64
import os import os
import json import json
import re import re
from dataclasses import dataclass, field from dataclasses import dataclass
from typing import Any, Callable, Dict, List, Optional from typing import Any, Callable, Dict, List, Optional
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -135,10 +135,12 @@ class ORALoop:
- auto : pHash toujours, VLM seulement si confiance < 0.95 - auto : pHash toujours, VLM seulement si confiance < 0.95
""" """
def __init__(self, max_retries: int = 2, max_steps: int = 50, verify_level: str = 'auto'): def __init__(self, max_retries: int = 2, max_steps: int = 50, verify_level: str = 'auto',
should_continue: Optional[Callable[[], bool]] = None):
self.max_retries = max_retries self.max_retries = max_retries
self.max_steps = max_steps self.max_steps = max_steps
self.verify_level = verify_level self.verify_level = verify_level
self._should_continue = should_continue or (lambda: True)
# Variables runtime injectées par le workflow # Variables runtime injectées par le workflow
self._variables: Dict[str, Any] = {} self._variables: Dict[str, Any] = {}
@@ -450,6 +452,11 @@ Règles:
logger.warning("🧠 [ORA/instruction] CognitiveContext non disponible — mode dégradé") logger.warning("🧠 [ORA/instruction] CognitiveContext non disponible — mode dégradé")
for step_num in range(self.max_steps): for step_num in range(self.max_steps):
if not self._should_continue():
logger.info("⛔ [ORA/instruction] Arrêt demandé")
return LoopResult(success=False, steps_completed=step_num,
total_steps=self.max_steps, reason="stopped")
logger.info(f"\n{'='*60}") logger.info(f"\n{'='*60}")
logger.info(f"📋 [ORA/instruction] Étape {step_num + 1}/{self.max_steps}") logger.info(f"📋 [ORA/instruction] Étape {step_num + 1}/{self.max_steps}")
@@ -746,6 +753,10 @@ Règles:
logger.info(f"🚀 [ORA] Démarrage workflow: {total} étapes, verify={self.verify_level}, retries={self.max_retries}") logger.info(f"🚀 [ORA] Démarrage workflow: {total} étapes, verify={self.verify_level}, retries={self.max_retries}")
for i, step in enumerate(steps): for i, step in enumerate(steps):
if not self._should_continue():
logger.info("⛔ [ORA] Arrêt demandé")
return LoopResult(success=False, steps_completed=i, total_steps=total, reason="stopped")
logger.info(f"\n{'='*60}") logger.info(f"\n{'='*60}")
logger.info(f"📋 [ORA] Étape {i+1}/{total}: {step.get('action_type', '?')}{step.get('label', '')}") logger.info(f"📋 [ORA] Étape {i+1}/{total}: {step.get('action_type', '?')}{step.get('label', '')}")

View File

@@ -1430,7 +1430,10 @@ def run_workflow_verified(execution_id: str, workflow_id: str, app):
# --- Créer et lancer la boucle ORA --- # --- Créer et lancer la boucle ORA ---
from core.execution.observe_reason_act import ORALoop from core.execution.observe_reason_act import ORALoop
ora = ORALoop(max_retries=2, max_steps=50, verify_level='auto') ora = ORALoop(
max_retries=2, max_steps=50, verify_level='auto',
should_continue=lambda: not _execution_state.get('should_stop', False)
)
ora._variables = _execution_state.get('variables', {}) ora._variables = _execution_state.get('variables', {})
# Créer les ExecutionStep en amont pour le suivi # Créer les ExecutionStep en amont pour le suivi
@@ -1955,6 +1958,7 @@ def execute_instruction():
max_retries=2, max_retries=2,
max_steps=max_steps, max_steps=max_steps,
verify_level=verify_level, verify_level=verify_level,
should_continue=lambda: not _execution_state.get('should_stop', False),
) )
logger.info(f"🚀 [Instruction] Démarrage: '{instruction}' (exec_id={exec_id})") logger.info(f"🚀 [Instruction] Démarrage: '{instruction}' (exec_id={exec_id})")