feat(lea): expose competence replay api
This commit is contained in:
@@ -41,6 +41,16 @@ from .execution_plan_runner import (
|
||||
inject_plan_into_queue,
|
||||
)
|
||||
|
||||
try:
|
||||
from core.competences.catalog import load_competences
|
||||
from core.competences.replay import build_competence_replay_payload, find_competence
|
||||
COMPETENCE_API_AVAILABLE = True
|
||||
except Exception: # pragma: no cover - allows partial deployments
|
||||
load_competences = None
|
||||
build_competence_replay_payload = None
|
||||
find_competence = None
|
||||
COMPETENCE_API_AVAILABLE = False
|
||||
|
||||
# Pipeline d'anonymisation PII (OCR + NER côté serveur).
|
||||
# Import paresseux : on ne charge pas docTR tant qu'aucune image n'est reçue.
|
||||
try:
|
||||
@@ -688,6 +698,14 @@ class RawReplayRequest(BaseModel):
|
||||
params: Optional[Dict[str, Any]] = None
|
||||
|
||||
|
||||
class CompetenceReplayRequest(BaseModel):
|
||||
"""Requête de test/replay supervisé d'une compétence Léa YAML."""
|
||||
supervised: bool = True
|
||||
start_replay: bool = False
|
||||
session_id: str = ""
|
||||
machine_id: Optional[str] = None
|
||||
|
||||
|
||||
class SingleActionRequest(BaseModel):
|
||||
"""Requête d'exécution d'une seule action (mode Copilot)."""
|
||||
action: Dict[str, Any]
|
||||
@@ -2074,6 +2092,81 @@ async def list_workflows(machine_id: Optional[str] = None):
|
||||
return result
|
||||
|
||||
|
||||
def _require_competence_api() -> None:
|
||||
if not COMPETENCE_API_AVAILABLE:
|
||||
raise HTTPException(status_code=503, detail="Catalogue compétences Léa indisponible")
|
||||
|
||||
|
||||
def _parse_competence_states(state: Optional[str]) -> Optional[List[str]]:
|
||||
if not state:
|
||||
return None
|
||||
states = [part.strip() for part in state.split(",") if part.strip()]
|
||||
return states or None
|
||||
|
||||
|
||||
@app.get("/api/v1/lea/competences")
|
||||
async def list_lea_competences(state: Optional[str] = None):
|
||||
"""Lister les compétences YAML connues par Léa, sans dépendance au VWB."""
|
||||
_require_competence_api()
|
||||
states = _parse_competence_states(state)
|
||||
competences = load_competences(states=states) # type: ignore[misc]
|
||||
return {
|
||||
"success": True,
|
||||
"competences": [competence.to_dict() for competence in competences],
|
||||
"total": len(competences),
|
||||
"states_filter": states,
|
||||
}
|
||||
|
||||
|
||||
@app.get("/api/v1/lea/competences/{competence_id}")
|
||||
async def get_lea_competence(competence_id: str):
|
||||
"""Retourner une compétence YAML et son plan de test supervisé."""
|
||||
_require_competence_api()
|
||||
try:
|
||||
competence = find_competence(competence_id) # type: ignore[misc]
|
||||
payload = build_competence_replay_payload(competence_id, supervised=True) # type: ignore[misc]
|
||||
except KeyError:
|
||||
raise HTTPException(status_code=404, detail=f"Compétence '{competence_id}' introuvable")
|
||||
return {
|
||||
"success": True,
|
||||
"competence": competence.to_dict(),
|
||||
"supervised_replay_preview": payload,
|
||||
}
|
||||
|
||||
|
||||
@app.post("/api/v1/lea/competences/{competence_id}/replay")
|
||||
async def replay_lea_competence(competence_id: str, request: CompetenceReplayRequest):
|
||||
"""Planifier ou lancer le replay supervisé d'une compétence Léa YAML."""
|
||||
_require_competence_api()
|
||||
try:
|
||||
payload = build_competence_replay_payload( # type: ignore[misc]
|
||||
competence_id,
|
||||
supervised=request.supervised,
|
||||
machine_id=request.machine_id,
|
||||
session_id=request.session_id,
|
||||
)
|
||||
except KeyError:
|
||||
raise HTTPException(status_code=404, detail=f"Compétence '{competence_id}' introuvable")
|
||||
|
||||
if not request.start_replay:
|
||||
return {
|
||||
"success": True,
|
||||
"status": "planned",
|
||||
"competence_id": competence_id,
|
||||
"raw_replay_payload": payload,
|
||||
}
|
||||
|
||||
replay_request = RawReplayRequest(**payload)
|
||||
replay_result = await start_raw_replay(replay_request)
|
||||
return {
|
||||
"success": True,
|
||||
"status": "started",
|
||||
"competence_id": competence_id,
|
||||
"raw_replay_payload": payload,
|
||||
"replay": replay_result,
|
||||
}
|
||||
|
||||
|
||||
@app.post("/api/v1/traces/stream/reload-workflows")
|
||||
async def reload_workflows():
|
||||
"""Recharger les workflows depuis le disque.
|
||||
|
||||
Reference in New Issue
Block a user