"""Isolated test — just explain(). Checks it correctly uses final_verdict (set by verify_dual on agreement) to call /attribute with the right label_id, now that final_verdict is always pre-populated before explain() runs. Requires GROQ_API_KEY not needed here (no LLM call in explain) — only hits the live clAIm /attribute endpoint directly. Run from the veriscite/ root: python -m tests.test_explain_live """ import asyncio from app.graph.nodes import explain SAMPLE_CLAIM_CITATION = { "claim": "Attention mechanisms allow transformer models to capture " "long-range dependencies in sequential data without relying on recurrence", "citation_marker": "[1]", "reference_string": "Vaswani, A., Shazeer, N., Parmar, N., Uszkoreit, J., " "Jones, L., Gomez, A. N., Kaiser, L., & Polosukhin, I. (2017). " "Attention is all you need. In NeurIPS 2017.", "resolved_paper_id": "204e3073870fae3d05bcbc2f6a8e263d9b72e776", "evidence_text": ( "The dominant sequence transduction models are based on complex " "recurrent or convolutional neural networks in an encoder-decoder " "configuration. We propose a new simple network architecture, the " "Transformer, based solely on attention mechanisms, dispensing with " "recurrence and convolutions entirely." ), } # Mirrors exactly what verify_dual produces on agreement — final_verdict # already set, matching the current (post-bugfix) flow. SAMPLE_AUDIT = { "claim_citation": SAMPLE_CLAIM_CITATION, "winner_sentence": "We propose a new simple network architecture, the " "Transformer, based solely on attention mechanisms, " "dispensing with recurrence and convolutions entirely.", "attribution_available": True, "deberta_verdict": {"label": "SUPPORT", "confidence": 0.9658, "source": "deberta"}, "llm_verdict": {"label": "SUPPORT", "confidence": 1.0, "source": "llm"}, "agreement": True, "escalated": False, "escalation_retry_succeeded": None, "adjudicator_reasoning": None, "final_verdict": {"label": "SUPPORT", "confidence": 0.9658, "source": "deberta"}, "attribution": None, } async def main(): state = { "source_text": "", "claims": [SAMPLE_CLAIM_CITATION], "audits": [SAMPLE_AUDIT], "current_index": 0, "report": None, } result = await explain(state) audit = result["audits"][0] print("attribution_available:", audit["attribution_available"]) print("attribution (first 5 tokens):") for item in (audit["attribution"] or [])[:5]: print(" ", item) print("total tokens:", len(audit["attribution"] or [])) if __name__ == "__main__": asyncio.run(main())