fix(ORA): logger.info→print pour que les logs apparaissent dans nohup
Some checks failed
security-audit / Bandit (scan statique) (push) Successful in 12s
security-audit / pip-audit (CVE dépendances) (push) Successful in 12s
security-audit / Scan secrets (grep) (push) Successful in 8s
tests / Lint (ruff + black) (push) Successful in 14s
tests / Tests unitaires (sans GPU) (push) Failing after 15s
tests / Tests sécurité (critique) (push) Has been skipped
Some checks failed
security-audit / Bandit (scan statique) (push) Successful in 12s
security-audit / pip-audit (CVE dépendances) (push) Successful in 12s
security-audit / Scan secrets (grep) (push) Successful in 8s
tests / Lint (ruff + black) (push) Successful in 14s
tests / Tests unitaires (sans GPU) (push) Failing after 15s
tests / Tests sécurité (critique) (push) Has been skipped
Le logging Python ne traverse pas le nohup de Flask. Tous les autres modules (execute.py, intelligent_executor.py) utilisent print(). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user