Files
rpa_vision_v3/tests/unit/test_reasoning_model.py
Dom 806cc04b82 feat(p1z): centralize V4 reasoning model resolution (DGX-safe)
Remplace le default runtime dangereux `qwen2.5vl:7b` (absent du tunnel DGX
-> 404) des chemins V4/reasoning par un helper central get_reasoning_model().

- core/detection/vlm_config.py : + get_reasoning_model() + DEFAULT_REASONING_MODEL
  (qwen2.5vl:7b-rpa). Ordre : RPA_REASONING_MODEL -> RPA_VLM_MODEL/VLM_MODEL ->
  default DGX-safe. Pas d'appel reseau (lazy, safe a l'import).
- core/execution/input_handler.py, observe_reason_act.py (x3),
  core/cognition/vram_orchestrator.py : migration des 5 call-sites.
- tests/unit/test_reasoning_model.py : 8 tests (default DGX-safe, ordre de
  resolution, non-regression wiring des 3 modules V4).

Hors scope (signale lot P1.w) : DEFAULT_VLM_MODEL=gemma4:latest reste fallback
de get_vlm_model(). Client gele non touche.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 16:23:10 +02:00

83 lines
3.0 KiB
Python

"""Tests P1.z — résolution centralisée du modèle V4/reasoning (DGX-safe).
Garantit que les chemins V4/reasoning (ORALoop, détection dialogue/popup,
vram_orchestrator) ne tombent plus sur le default brut `qwen2.5vl:7b` (absent
du tunnel DGX → 404) quand `RPA_REASONING_MODEL` n'est pas positionné.
"""
import importlib
import os
import pytest
from core.detection import vlm_config
# Le default historique dangereux : présent dans aucun modèle DGX → 404.
DANGEROUS_RAW_DEFAULT = "qwen2.5vl:7b"
# Les 3 env vars qui influencent la résolution reasoning.
_REASONING_ENVS = ("RPA_REASONING_MODEL", "RPA_VLM_MODEL", "VLM_MODEL")
@pytest.fixture
def clean_reasoning_env(monkeypatch):
"""Neutralise toute env reasoning/VLM pour tester le default pur."""
for var in _REASONING_ENVS:
monkeypatch.delenv(var, raising=False)
return monkeypatch
def test_default_is_dgx_safe(clean_reasoning_env):
"""Sans aucune env, le default ne doit PAS être `qwen2.5vl:7b` brut."""
model = vlm_config.get_reasoning_model()
assert model != DANGEROUS_RAW_DEFAULT
# Le default doit pointer vers un modèle présent sur DGX (tag -rpa).
assert model == vlm_config.DEFAULT_REASONING_MODEL
assert "-rpa" in model
def test_rpa_reasoning_model_has_priority(clean_reasoning_env):
"""RPA_REASONING_MODEL prime sur tout le reste."""
clean_reasoning_env.setenv("RPA_REASONING_MODEL", "mon-modele:custom")
clean_reasoning_env.setenv("RPA_VLM_MODEL", "autre:vlm")
assert vlm_config.get_reasoning_model() == "mon-modele:custom"
def test_falls_back_to_vlm_model(clean_reasoning_env):
"""Sans RPA_REASONING_MODEL, on hérite de la config VLM existante."""
clean_reasoning_env.setenv("RPA_VLM_MODEL", "qwen2.5vl:7b-rpa")
assert vlm_config.get_reasoning_model() == "qwen2.5vl:7b-rpa"
def test_falls_back_to_legacy_vlm_model_alias(clean_reasoning_env):
"""L'alias de compat VLM_MODEL est honoré en dernier recours avant default."""
clean_reasoning_env.setenv("VLM_MODEL", "qwen2.5vl:7b-rpa")
assert vlm_config.get_reasoning_model() == "qwen2.5vl:7b-rpa"
@pytest.mark.parametrize(
"module_name",
[
"core.execution.input_handler",
"core.execution.observe_reason_act",
"core.cognition.vram_orchestrator",
],
)
def test_v4_modules_have_no_raw_hardcoded_default(module_name):
"""Non-régression : aucun module V4 ne hardcode plus
`os.environ.get("RPA_REASONING_MODEL", "qwen2.5vl:7b")`."""
module = importlib.import_module(module_name)
source = open(module.__file__, encoding="utf-8").read()
assert 'RPA_REASONING_MODEL", "qwen2.5vl:7b"' not in source, (
f"{module_name} hardcode encore le default dangereux qwen2.5vl:7b"
)
def test_vram_orchestrator_reasoning_model_is_dgx_safe(clean_reasoning_env):
"""Le constant module-level REASONING_MODEL, recalculé sans env,
ne doit pas valoir le default brut dangereux."""
from core.cognition import vram_orchestrator
importlib.reload(vram_orchestrator)
assert vram_orchestrator.REASONING_MODEL != DANGEROUS_RAW_DEFAULT