"""Thin client around clAIm's deployed HF Space API. Reuses the existing fine-tuned DeBERTa-v3 NLI model and IntGrad attribution endpoint rather than reloading/retraining a model. See clAIm report Section 2.2 for endpoint definitions. """ import httpx CLAIM_BASE_URL = "https://minoola-claim-ai.hf.space" LABEL2ID = {"SUPPORT": 0, "NOT_ENOUGH_INFO": 1, "CONTRADICT": 2} async def analyze(claim: str, evidence: str) -> dict: """Calls clAIm's /analyze endpoint: sentence-split + NLI verdict. Request: {"claim": ..., "evidence": ...} Response: {"winner": {"sentence", "label", "confidence", "sentence_index"}, "supporting": [...], "all_scores": [...], "attribution_available": bool} """ async with httpx.AsyncClient(timeout=30.0) as client: resp = await client.post( f"{CLAIM_BASE_URL}/analyze", json={"claim": claim, "evidence": evidence}, ) resp.raise_for_status() return resp.json() async def attribute(claim: str, winner_sentence: str, label_id: int) -> list[dict]: """Calls clAIm's /attribute endpoint: Captum Integrated Gradients, N=25. Must be called with the WINNER sentence only (not the full evidence text), and label_id must match the winner's predicted label. Request: {"claim": ..., "evidence": ..., "label_id": 0|1|2} Response: [{"token": ..., "score": ...}, ...] """ async with httpx.AsyncClient(timeout=30.0) as client: resp = await client.post( f"{CLAIM_BASE_URL}/attribute", json={"claim": claim, "evidence": winner_sentence, "label_id": label_id}, ) resp.raise_for_status() return resp.json()