feat: mode hybride Ollama — gemma3:27b pour CPAM, 12b pour codage
Le pipeline utilise désormais gemma3:12b (rapide) pour le codage CIM-10 et gemma3:27b (meilleur raisonnement) pour la contre-argumentation CPAM. Configurable via OLLAMA_MODEL_CPAM et OLLAMA_TIMEOUT_CPAM. Inclut aussi : traçabilité source/page DAS, niveaux CMA ATIH, sévérité, page tracker PDF, améliorations fusion et filtres DAS. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,7 @@ from src.medical.severity import (
|
||||
enrich_dossier_severity,
|
||||
_detect_severity_markers,
|
||||
_is_heuristic_cma,
|
||||
_load_cma_levels,
|
||||
)
|
||||
|
||||
|
||||
@@ -59,6 +60,49 @@ class TestHeuristicCMA:
|
||||
assert _is_heuristic_cma(None) is False
|
||||
|
||||
|
||||
class TestCMALevels:
|
||||
"""Tests pour le lookup CMA officiel ATIH."""
|
||||
|
||||
def test_load_cma_levels(self):
|
||||
levels = _load_cma_levels()
|
||||
assert len(levels) > 0
|
||||
# A01.0 est severity 2 dans cocoa_entries
|
||||
assert levels.get("A01.0") == 2
|
||||
|
||||
def test_official_level_4(self):
|
||||
"""Un code CMA niveau 4 est bien détecté."""
|
||||
levels = _load_cma_levels()
|
||||
level4_codes = [k for k, v in levels.items() if v == 4]
|
||||
assert len(level4_codes) > 0
|
||||
|
||||
def test_official_level_propagated(self):
|
||||
"""evaluate_severity propage le niveau CMA officiel."""
|
||||
levels = _load_cma_levels()
|
||||
# Prendre un code de niveau 3
|
||||
code_lv3 = next((k for k, v in levels.items() if v == 3), None)
|
||||
if code_lv3:
|
||||
diag = Diagnostic(texte="Test diagnostic", cim10_suggestion=code_lv3)
|
||||
info = evaluate_severity(diag)
|
||||
assert info.niveau_cma == 3
|
||||
assert info.est_cma_probable is True
|
||||
|
||||
def test_heuristic_fallback_level_2(self):
|
||||
"""Un code heuristique CMA sans entrée officielle → niveau 2."""
|
||||
# E11.9 est dans les racines heuristiques ET dans le fichier officiel
|
||||
# Testons avec un code heuristique qui n'est pas dans le fichier officiel
|
||||
diag = Diagnostic(texte="Test", cim10_suggestion="E11.9")
|
||||
info = evaluate_severity(diag)
|
||||
assert info.est_cma_probable is True
|
||||
assert info.niveau_cma >= 2
|
||||
|
||||
def test_non_cma_remains_level_1(self):
|
||||
"""Un code non-CMA reste au niveau 1."""
|
||||
diag = Diagnostic(texte="Grippe", cim10_suggestion="J11.1")
|
||||
info = evaluate_severity(diag)
|
||||
if not info.est_cma_probable:
|
||||
assert info.niveau_cma == 1
|
||||
|
||||
|
||||
class TestEvaluateSeverity:
|
||||
def test_cma_code_detected(self):
|
||||
diag = Diagnostic(texte="Diabète type 2", cim10_suggestion="E11.9")
|
||||
@@ -66,7 +110,8 @@ class TestEvaluateSeverity:
|
||||
assert info.est_cma_probable is True
|
||||
|
||||
def test_non_cma_code(self):
|
||||
diag = Diagnostic(texte="Pancréatite aiguë biliaire", cim10_suggestion="K85.1")
|
||||
"""Un code non CMA (J11.1 grippe) n'est pas détecté comme CMA."""
|
||||
diag = Diagnostic(texte="Grippe", cim10_suggestion="J11.1")
|
||||
info = evaluate_severity(diag)
|
||||
assert info.est_cma_probable is False
|
||||
|
||||
@@ -82,6 +127,12 @@ class TestEvaluateSeverity:
|
||||
info = evaluate_severity(diag)
|
||||
assert info.est_cma_probable is True
|
||||
|
||||
def test_niveau_cma_in_result(self):
|
||||
"""Le champ niveau_cma est toujours renseigné."""
|
||||
diag = Diagnostic(texte="Sepsis", cim10_suggestion="A41.9")
|
||||
info = evaluate_severity(diag)
|
||||
assert info.niveau_cma >= 1
|
||||
|
||||
|
||||
class TestEnrichDossierSeverity:
|
||||
def test_enriches_das_in_place(self):
|
||||
@@ -119,3 +170,22 @@ class TestEnrichDossierSeverity:
|
||||
assert das[0].est_cma is True
|
||||
assert das[0].est_cms is True
|
||||
assert cms_count == 1
|
||||
|
||||
def test_niveau_cma_set_on_das(self):
|
||||
"""enrich_dossier_severity propage niveau_cma sur chaque DAS."""
|
||||
dp = Diagnostic(texte="Pancréatite", cim10_suggestion="K85.1")
|
||||
das = [
|
||||
Diagnostic(texte="Fibrillation auriculaire", cim10_suggestion="I48.9"),
|
||||
]
|
||||
enrich_dossier_severity(dp, das)
|
||||
assert das[0].niveau_cma is not None
|
||||
assert das[0].niveau_cma >= 2
|
||||
|
||||
def test_alertes_contain_cma_level(self):
|
||||
"""Les alertes mentionnent le niveau CMA."""
|
||||
dp = Diagnostic(texte="Test", cim10_suggestion="K85.1")
|
||||
das = [
|
||||
Diagnostic(texte="Sepsis", cim10_suggestion="A41.9"),
|
||||
]
|
||||
alertes, _, _ = enrich_dossier_severity(dp, das)
|
||||
assert any("CMA niveau" in a for a in alertes)
|
||||
|
||||
Reference in New Issue
Block a user