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
- 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}")
import sys; sys.stdout.write(f" [OCR-V2] target='{target_text}' bbox={anchor_bbox}\n"); sys.stdout.flush()
logger.debug(f"[Grounding/OCR] target='{target_text}' bbox={anchor_bbox}")
if not target_text:
return None

View File

@@ -17,7 +17,7 @@ import base64
import os
import json
import re
from dataclasses import dataclass, field
from dataclasses import dataclass
from typing import Any, Callable, Dict, List, Optional
logger = logging.getLogger(__name__)
@@ -135,10 +135,12 @@ class ORALoop:
- 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_steps = max_steps
self.verify_level = verify_level
self._should_continue = should_continue or (lambda: True)
# Variables runtime injectées par le workflow
self._variables: Dict[str, Any] = {}
@@ -450,6 +452,11 @@ Règles:
logger.warning("🧠 [ORA/instruction] CognitiveContext non disponible — mode dégradé")
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"📋 [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}")
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"📋 [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 ---
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', {})
# Créer les ExecutionStep en amont pour le suivi
@@ -1955,6 +1958,7 @@ def execute_instruction():
max_retries=2,
max_steps=max_steps,
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})")