122 lines
4.1 KiB
Python
122 lines
4.1 KiB
Python
"""Tests pour le feature flag AGENT_CHAT_ENABLE_OWL (C1b).
|
|
|
|
Contexte : depuis 2026-05-25, OWL-v2 ne se charge plus au boot du service
|
|
rpa-agent-chat par défaut (économie ~600 MiB VRAM constatée par Codex après
|
|
restart C1). Activation via AGENT_CHAT_ENABLE_OWL=1.
|
|
|
|
Référence : inbox_claude/2026-05-25_1327_codex-to-claude_C1-post-restart-ok-c1b-vram.md
|
|
Fix : agent_chat/autonomous_planner.py _init_visual_detection() l. 139-...
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
if str(ROOT) not in sys.path:
|
|
sys.path.insert(0, str(ROOT))
|
|
|
|
|
|
@pytest.mark.unit
|
|
def test_owl_skipped_by_default(monkeypatch):
|
|
"""Sans AGENT_CHAT_ENABLE_OWL, OWL ne doit PAS se charger au boot."""
|
|
monkeypatch.delenv("AGENT_CHAT_ENABLE_OWL", raising=False)
|
|
from agent_chat.autonomous_planner import AutonomousPlanner
|
|
|
|
planner = AutonomousPlanner(llm_model="qwen2.5:7b")
|
|
assert planner._owl_detector is None, (
|
|
f"OWL chargé alors que flag OFF (économie VRAM perdue) : "
|
|
f"{planner._owl_detector}"
|
|
)
|
|
|
|
|
|
@pytest.mark.unit
|
|
def test_owl_skipped_when_flag_zero(monkeypatch):
|
|
"""AGENT_CHAT_ENABLE_OWL=0 → OWL skip."""
|
|
monkeypatch.setenv("AGENT_CHAT_ENABLE_OWL", "0")
|
|
from agent_chat.autonomous_planner import AutonomousPlanner
|
|
|
|
planner = AutonomousPlanner(llm_model="qwen2.5:7b")
|
|
assert planner._owl_detector is None
|
|
|
|
|
|
@pytest.mark.unit
|
|
def test_owl_skipped_when_flag_false(monkeypatch):
|
|
"""AGENT_CHAT_ENABLE_OWL=false → OWL skip (alias accepté)."""
|
|
monkeypatch.setenv("AGENT_CHAT_ENABLE_OWL", "false")
|
|
from agent_chat.autonomous_planner import AutonomousPlanner
|
|
|
|
planner = AutonomousPlanner(llm_model="qwen2.5:7b")
|
|
assert planner._owl_detector is None
|
|
|
|
|
|
@pytest.mark.unit
|
|
def test_owl_init_attempted_when_flag_one(monkeypatch):
|
|
"""AGENT_CHAT_ENABLE_OWL=1 → tentative d'init (succès ou échec rattrapé).
|
|
|
|
Le test ne valide PAS que OWL charge effectivement (dépend GPU + modèle
|
|
HF disponible), juste que le code passe la garde du flag et tente l'init.
|
|
On mocke OwlDetector pour vérifier qu'il est instancié.
|
|
"""
|
|
monkeypatch.setenv("AGENT_CHAT_ENABLE_OWL", "1")
|
|
from agent_chat import autonomous_planner as ap_module
|
|
|
|
calls = []
|
|
|
|
class FakeOwl:
|
|
def __init__(self, **kwargs):
|
|
calls.append(kwargs)
|
|
|
|
monkeypatch.setattr(ap_module, "OwlDetector", FakeOwl)
|
|
monkeypatch.setattr(ap_module, "VISUAL_DETECTION_AVAILABLE", True)
|
|
|
|
planner = ap_module.AutonomousPlanner(llm_model="qwen2.5:7b")
|
|
assert planner._owl_detector is not None, (
|
|
"OWL doit être instancié quand AGENT_CHAT_ENABLE_OWL=1"
|
|
)
|
|
assert len(calls) == 1
|
|
assert calls[0].get("confidence_threshold") == 0.1
|
|
|
|
|
|
@pytest.mark.unit
|
|
def test_owl_device_override(monkeypatch):
|
|
"""AGENT_CHAT_OWL_DEVICE=cpu force le device CPU même si CUDA dispo."""
|
|
monkeypatch.setenv("AGENT_CHAT_ENABLE_OWL", "1")
|
|
monkeypatch.setenv("AGENT_CHAT_OWL_DEVICE", "cpu")
|
|
from agent_chat import autonomous_planner as ap_module
|
|
|
|
calls = []
|
|
|
|
class FakeOwl:
|
|
def __init__(self, **kwargs):
|
|
calls.append(kwargs)
|
|
|
|
monkeypatch.setattr(ap_module, "OwlDetector", FakeOwl)
|
|
monkeypatch.setattr(ap_module, "VISUAL_DETECTION_AVAILABLE", True)
|
|
|
|
ap_module.AutonomousPlanner(llm_model="qwen2.5:7b")
|
|
assert calls[0].get("device") == "cpu"
|
|
|
|
|
|
@pytest.mark.unit
|
|
def test_owl_init_exception_caught(monkeypatch):
|
|
"""Si OWL crash à l'init (OOM CUDA, modèle absent, etc.), AutonomousPlanner
|
|
doit continuer à booter avec _owl_detector=None."""
|
|
monkeypatch.setenv("AGENT_CHAT_ENABLE_OWL", "1")
|
|
from agent_chat import autonomous_planner as ap_module
|
|
|
|
class CrashOwl:
|
|
def __init__(self, **kwargs):
|
|
raise RuntimeError("CUDA out of memory (simulation)")
|
|
|
|
monkeypatch.setattr(ap_module, "OwlDetector", CrashOwl)
|
|
monkeypatch.setattr(ap_module, "VISUAL_DETECTION_AVAILABLE", True)
|
|
|
|
planner = ap_module.AutonomousPlanner(llm_model="qwen2.5:7b")
|
|
assert planner._owl_detector is None, (
|
|
"L'exception doit être catchée — AutonomousPlanner ne doit pas crash"
|
|
)
|