Added Wiki seed + retrieval bones, Whisper online integration, Documentation Agent v1 and Doctor Gradio tab
8d6e5f8 | """Documentation Agent tests. OWNER: Person A — Day 3/4. | |
| The LLM is mocked (no network / key needed). The patient-wiki write is pointed | |
| at a tmp dir via CLINIQ_WIKI_DIR so tests never touch the real repo. | |
| """ | |
| from __future__ import annotations | |
| import json | |
| from unittest.mock import patch | |
| import pytest | |
| from app.agents.documentation import api | |
| from app.agents.wiki import api as wiki_api | |
| from app.llm.router import CompletionResult | |
| _TRANSCRIPT = ( | |
| "Doctor: how is the blood pressure at home? " | |
| "Patient: I stopped the amlodipine tablet last week, having headaches and dizziness. " | |
| "Doctor: your BP today is 162 over 98." | |
| ) | |
| _MODEL_JSON = { | |
| "soap": { | |
| "subjective": "52M, hypertensive, stopped amlodipine, 2-day headache and dizziness.", | |
| "objective": "BP 162/98, HR 84, afebrile.", | |
| "assessment": "Uncontrolled essential hypertension, likely non-adherence.", | |
| "plan": "Restart and uptitrate amlodipine; home BP log; review in 2 weeks.", | |
| }, | |
| "icd10_suggestions": [{"code": "I10", "label": "Essential hypertension", "confidence": 0.92}], | |
| "guideline_suggestions": ["Combination therapy preferred in stage-2 HTN."], | |
| "referral_needed": False, | |
| "confidence_overall": 0.83, | |
| } | |
| def _fake_completion(text: str) -> CompletionResult: | |
| return CompletionResult( | |
| text=text, | |
| model="groq/qwen/qwen3-32b", | |
| latency_ms=900.0, | |
| prompt_tokens=400, | |
| completion_tokens=180, | |
| ) | |
| def mock_llm(): | |
| """Patch the router so draft_soap returns our canned JSON.""" | |
| with patch.object(api, "complete") as m: | |
| m.return_value = _fake_completion(json.dumps(_MODEL_JSON)) | |
| yield m | |
| def _tmp_wiki(tmp_path, monkeypatch): | |
| monkeypatch.setenv("CLINIQ_WIKI_DIR", str(tmp_path / "wiki")) | |
| monkeypatch.setenv("CLINIQ_WIKI_HISTORY_DIR", str(tmp_path / "history")) | |
| # --- draft_soap --------------------------------------------------------------- | |
| def test_draft_soap_assembles_validated_draft(mock_llm) -> None: | |
| draft = api.draft_soap(patient_id="p-001", transcript=_TRANSCRIPT) | |
| assert draft.patient_id == "p-001" | |
| assert draft.draft_id.startswith("soap-") | |
| assert "hypertension" in draft.soap.assessment.lower() | |
| assert draft.model == "groq/qwen/qwen3-32b" | |
| assert draft.confidence_overall == pytest.approx(0.83) | |
| assert draft.icd10_suggestions[0].code == "I10" | |
| def test_draft_soap_guarantees_guideline_citation(mock_llm) -> None: | |
| """The hypertension consult must cite the hypertension wiki page (audit contract).""" | |
| draft = api.draft_soap(patient_id="p-001", transcript=_TRANSCRIPT) | |
| cited = {c.source_id for c in draft.sources} | |
| assert "conditions/hypertension" in cited | |
| assert all(c.source_type == "wiki" for c in draft.sources) | |
| def test_draft_soap_requires_input() -> None: | |
| with pytest.raises(ValueError): | |
| api.draft_soap(patient_id="p-001") | |
| def test_draft_soap_tolerates_fenced_json(monkeypatch) -> None: | |
| fenced = "```json\n" + json.dumps(_MODEL_JSON) + "\n```" | |
| with patch.object(api, "complete", return_value=_fake_completion(fenced)): | |
| draft = api.draft_soap(patient_id="p-001", transcript=_TRANSCRIPT) | |
| assert draft.soap.plan.startswith("Restart") | |
| # --- approve_draft + wiki persistence ---------------------------------------- | |
| def test_approve_writes_patient_page_with_edits(mock_llm) -> None: | |
| draft = api.draft_soap(patient_id="p-007", transcript=_TRANSCRIPT) | |
| ref = api.approve_draft(draft, edits={"plan": "EDITED: amlodipine 10 mg, review day 7."}) | |
| assert ref.patient_id == "p-007" | |
| assert ref.version # content hash present | |
| page = wiki_api.get_patient_page("p-007") | |
| assert page is not None | |
| assert "## Encounter History" in page | |
| assert "EDITED: amlodipine 10 mg" in page | |
| assert draft.draft_id in page | |
| def test_get_patient_page_absent_returns_none() -> None: | |
| assert wiki_api.get_patient_page("does-not-exist") is None | |