diff --git a/core/execution/observe_reason_act.py b/core/execution/observe_reason_act.py index 8cc414c40..cf9e07614 100644 --- a/core/execution/observe_reason_act.py +++ b/core/execution/observe_reason_act.py @@ -14,15 +14,6 @@ import logging import time import subprocess import sys - -# Forcer les logs ORA dans stdout (visible dans nohup) -logging.basicConfig(level=logging.INFO, stream=sys.stdout, - format='%(message)s', force=False) -if not logging.getLogger(__name__).handlers: - handler = logging.StreamHandler(sys.stdout) - handler.setFormatter(logging.Formatter('%(message)s')) - logging.getLogger(__name__).addHandler(handler) - logging.getLogger(__name__).setLevel(logging.INFO) import base64 import os import json @@ -171,7 +162,7 @@ class ORALoop: window_title = self._get_active_window_title() ts = time.time() - logger.info(f"👁 [ORA/observe] titre='{window_title}' phash={phash}") + print(f"👁 [ORA/observe] titre='{window_title}' phash={phash}") return Observation( screenshot=screenshot, phash=phash, @@ -284,7 +275,7 @@ class ORALoop: expected_after=expected, confidence=confidence, ) - logger.info(f"🧠 [ORA/reason] {decision.action} target='{decision.target}' value='{decision.value[:50]}'") + print(f"🧠 [ORA/reason] {decision.action} target='{decision.target}' value='{decision.value[:50]}'") return decision # ─── Phase 2b : RAISONNE (mode instruction) ───────── @@ -363,7 +354,7 @@ Règles: ollama_url = os.environ.get("OLLAMA_URL", "http://localhost:11434") model = os.environ.get("RPA_REASONING_MODEL", "qwen2.5vl:7b") - logger.info(f"🧠 [ORA/reason_instruction] Appel VLM {model}...") + print(f"🧠 [ORA/reason_instruction] Appel VLM {model}...") response = requests.post( f"{ollama_url}/api/generate", @@ -452,7 +443,7 @@ Règles: Returns: LoopResult. """ - logger.info(f"🚀 [ORA/instruction] Démarrage: '{instruction}' (max {self.max_steps} étapes)") + print(f"🚀 [ORA/instruction] Démarrage: '{instruction}' (max {self.max_steps} étapes)") # --- Initialiser le contexte cognitif --- if COGNITIVE_AVAILABLE and CognitiveContext is not None: @@ -467,8 +458,8 @@ Règles: 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}") + print(f"\n{'='*60}") + print(f"📋 [ORA/instruction] Étape {step_num + 1}/{self.max_steps}") # --- 1. Observer --- pre = self.observe() @@ -478,7 +469,7 @@ Règles: # --- Objectif atteint --- if decision.done: - logger.info(f"✅ [ORA/instruction] Objectif atteint en {step_num + 1} étapes: {decision.reasoning}") + print(f"✅ [ORA/instruction] Objectif atteint en {step_num + 1} étapes: {decision.reasoning}") if self.ctx: self.ctx.record_action('done', decision.target, result='Objectif atteint', success=True) return LoopResult( @@ -555,7 +546,7 @@ Règles: if not verification.success: retried = False for retry in range(self.max_retries): - logger.info(f"🔄 [ORA/instruction] Retry {retry + 1}/{self.max_retries}") + print(f"🔄 [ORA/instruction] Retry {retry + 1}/{self.max_retries}") pre_retry = self.observe() self.act(decision) time.sleep(0.3) @@ -563,7 +554,7 @@ Règles: verification = self.verify(pre_retry, post_retry, decision) if verification.success: retried = True - logger.info(f"✅ [ORA/instruction] Retry {retry + 1} réussi") + print(f"✅ [ORA/instruction] Retry {retry + 1} réussi") if self.ctx: self.ctx.record_action( decision.action, decision.target, @@ -615,7 +606,7 @@ Règles: if step_params is None: step_params = {} - logger.info(f"🎯 [ORA/act] {decision.action} target='{decision.target}' value='{decision.value[:50]}'") + print(f"🎯 [ORA/act] {decision.action} target='{decision.target}' value='{decision.value[:50]}'") try: if decision.action == 'click': @@ -686,7 +677,7 @@ Règles: distance = self._phash_distance(pre.phash, post.phash) change_level = self._classify_change(distance) - logger.info(f"🔍 [ORA/verify] pHash distance={distance} → {change_level}") + print(f"🔍 [ORA/verify] pHash distance={distance} → {change_level}") # Déterminer le succès selon le niveau de changement if change_level == 'same': @@ -720,10 +711,10 @@ Règles: detail += f" | VLM: matches={matches_expected}, état='{actual_state[:80]}'" # Le VLM a le dernier mot success = matches_expected - logger.info(f"🔍 [ORA/verify/VLM] matches={matches_expected} état='{actual_state[:60]}'") + print(f"🔍 [ORA/verify/VLM] matches={matches_expected} état='{actual_state[:60]}'") emoji = "✅" if success else "❌" - logger.info(f"{emoji} [ORA/verify] success={success} level={change_level} — {detail[:100]}") + print(f"{emoji} [ORA/verify] success={success} level={change_level} — {detail[:100]}") return VerificationResult( success=success, @@ -762,15 +753,15 @@ Règles: reason=f"Trop d'étapes ({total} > max {self.max_steps})" ) - logger.info(f"🚀 [ORA] Démarrage workflow: {total} étapes, verify={self.verify_level}, retries={self.max_retries}") + print(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', '')}") + print(f"\n{'='*60}") + print(f"📋 [ORA] Étape {i+1}/{total}: {step.get('action_type', '?')} — {step.get('label', '')}") # --- 1. Observer l'état pré-action --- pre = self.observe() @@ -820,7 +811,7 @@ Règles: # Réessayer retried = False for retry in range(self.max_retries): - logger.info(f"🔄 [ORA] Retry {retry+1}/{self.max_retries} pour étape {i+1}") + print(f"🔄 [ORA] Retry {retry+1}/{self.max_retries} pour étape {i+1}") pre_retry = self.observe() act_success = self.act(decision, step) time.sleep(0.3) @@ -828,7 +819,7 @@ Règles: verification = self.verify(pre_retry, post_retry, decision) if verification.success: retried = True - logger.info(f"✅ [ORA] Retry {retry+1} réussi") + print(f"✅ [ORA] Retry {retry+1} réussi") break if not retried and not verification.success: logger.warning(f"❌ [ORA] Étape {i+1} échouée après {self.max_retries} retries") @@ -841,7 +832,7 @@ Règles: if on_progress: on_progress(i + 1, total, verification) - logger.info(f"✅ [ORA] Workflow terminé avec succès: {total}/{total} étapes") + print(f"✅ [ORA] Workflow terminé avec succès: {total}/{total} étapes") return LoopResult(success=True, steps_completed=total, total_steps=total) # ═══════════════════════════════════════════════════════════ @@ -872,12 +863,12 @@ Règles: try: from core.execution.input_handler import _grounding_ui_tars click_label = target_desc or target_text - logger.info(f"🎯 [ORA/UI-TARS] Recherche: '{click_label}'") + print(f"🎯 [ORA/UI-TARS] Recherche: '{click_label}'") result = _grounding_ui_tars(target_text, target_desc) if result: x, y = result['x'], result['y'] method_used = 'ui_tars' - logger.info(f"✅ [ORA/UI-TARS] Trouvé à ({x}, {y})") + print(f"✅ [ORA/UI-TARS] Trouvé à ({x}, {y})") except Exception as e: logger.debug(f"⚠️ [ORA/UI-TARS] Erreur: {e}") @@ -902,7 +893,7 @@ Règles: result_tm = cv2.matchTemplate(screen_cv, anchor_cv, cv2.TM_CCOEFF_NORMED) _, max_val, _, max_loc = cv2.minMaxLoc(result_tm) elapsed_ms = (time.time() - t0) * 1000 - logger.info(f"⚡ [ORA/template] score={max_val:.3f} pos={max_loc} ({elapsed_ms:.0f}ms)") + print(f"⚡ [ORA/template] score={max_val:.3f} pos={max_loc} ({elapsed_ms:.0f}ms)") if max_val > 0.75: x = max_loc[0] + anchor_cv.shape[1] // 2 y = max_loc[1] + anchor_cv.shape[0] // 2 @@ -918,7 +909,7 @@ Règles: if result: x, y = result['x'], result['y'] method_used = 'ocr' - logger.info(f"🔍 [ORA/OCR] Trouvé à ({x}, {y})") + print(f"🔍 [ORA/OCR] Trouvé à ({x}, {y})") except Exception as e: logger.debug(f"⚠️ [ORA/OCR] Erreur: {e}") @@ -934,7 +925,7 @@ Règles: logger.error(f"❌ [ORA/click] Impossible de localiser '{target_text}' — aucune méthode n'a fonctionné") return False - logger.info(f"🖱️ [ORA/click] {decision.value} à ({x}, {y}) via {method_used}") + print(f"🖱️ [ORA/click] {decision.value} à ({x}, {y}) via {method_used}") if decision.value == 'double': pyautogui.doubleClick(x, y) @@ -999,7 +990,7 @@ Règles: # Raccourci clavier normal keys = value.split('+') - logger.info(f"⌨️ [ORA/hotkey] {'+'.join(keys)}") + print(f"⌨️ [ORA/hotkey] {'+'.join(keys)}") pyautogui.hotkey(*keys) return True @@ -1010,7 +1001,7 @@ Règles: except (ValueError, TypeError): timeout_ms = 5000 - logger.info(f"⏳ [ORA/wait] {timeout_ms}ms") + print(f"⏳ [ORA/wait] {timeout_ms}ms") time.sleep(timeout_ms / 1000) return True @@ -1036,7 +1027,7 @@ Règles: amount = int(nums[0]) scroll_value = amount if direction in ('up', 'left') else -amount - logger.info(f"📜 [ORA/scroll] {direction} x{amount}") + print(f"📜 [ORA/scroll] {direction} x{amount}") if direction in ('left', 'right'): pyautogui.hscroll(scroll_value)