File size: 6,229 Bytes
0ad6f75
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
from typing import Dict, List

_LIKELIHOOD_EMOJI = {"high": "πŸ”΄", "medium": "🟑", "low": "🟒"}
_SEVERITY_EMOJI = {"major": "πŸ”΄", "moderate": "🟑", "minor": "🟒"}


def _confidence_bar(score: float) -> str:
    filled = int(min(max(score, 0.0), 1.0) * 10)
    return "β–ˆ" * filled + "β–‘" * (10 - filled) + f"  {score:.0%}"


def format_diagnosis_output(
    entities: Dict,
    papers: List[Dict],
    reasoning_result: Dict,
    drug_interactions: Dict,
) -> str:
    out: List[str] = []

    # ── Header ──────────────────────────────────────────────────────────
    out.append("# πŸ₯ MedReason-RAG β€” Evidence-Grounded Clinical Reasoning")
    out.append(
        "> ⚠️ **EDUCATIONAL USE ONLY β€” NOT FOR CLINICAL DECISIONS.** "
        "Always consult a qualified healthcare professional.\n"
    )

    # ── Extracted entities ───────────────────────────────────────────────
    out.append("## πŸ” Extracted Medical Entities")
    for label, key in [
        ("Symptoms", "symptoms"),
        ("Lab Values", "labs"),
        ("Medications", "medications"),
        ("Known Diagnoses", "diagnoses"),
    ]:
        items = entities.get(key, [])
        value = ", ".join(items) if items else "*none detected*"
        out.append(f"- **{label}:** {value}")
    out.append("")

    # ── Retrieved evidence ───────────────────────────────────────────────
    out.append(f"## πŸ“š Retrieved PubMed Evidence  ({len(papers)} papers)")
    for i, p in enumerate(papers[:6]):
        title = p.get("title", "")[:90]
        year = p.get("year", "")
        pmid = p.get("pmid", "")
        url = p.get("url", f"https://pubmed.ncbi.nlm.nih.gov/{pmid}/")
        out.append(f"{i+1}. **{title}...** ({year}) β€” [PMID {pmid}]({url})")
    out.append("")

    # ── Critical alert ───────────────────────────────────────────────────
    critical = (reasoning_result.get("devils_advocate") or {}).get("critical_alert", "")
    if critical:
        out.append(f"## 🚨 Critical Alert\n> {critical}\n")

    # ── Differential diagnoses ───────────────────────────────────────────
    out.append("## πŸ“Š Differential Diagnoses")
    diagnoses = reasoning_result.get("diagnoses", [])
    if not diagnoses:
        out.append("*No diagnoses generated β€” please check your API key and try again.*")
    for i, dx in enumerate(diagnoses):
        likelihood = dx.get("likelihood", "Medium")
        emoji = _LIKELIHOOD_EMOJI.get(likelihood.lower(), "βšͺ")
        score = float(dx.get("confidence_score", 0.5))

        out.append(
            f"\n### {i+1}. {emoji} {dx.get('condition', 'Unknown')}  "
            f"*(Likelihood: {likelihood})*"
        )
        out.append(f"**Confidence:** `{_confidence_bar(score)}`")

        features = dx.get("supporting_features", [])
        if features:
            out.append(f"**Supporting Features:** {', '.join(features[:4])}")

        reasoning = dx.get("reasoning", "")
        if reasoning:
            out.append(f"**Reasoning:** {reasoning[:350]}")

        citations = dx.get("citations", [])
        if citations:
            out.append("**Evidence Citations:**")
            for cit in citations[:3]:
                pmid = cit.get("pmid", "")
                relevance = cit.get("relevance", "")[:100]
                v = cit.get("verification", {})
                icon = "βœ…" if v.get("supported") else "⚠️"
                conf = v.get("confidence", "")
                conf_str = f" *(sim={conf:.2f})*" if isinstance(conf, float) else ""
                out.append(
                    f"  - {icon} [PMID {pmid}](https://pubmed.ncbi.nlm.nih.gov/{pmid}/) "
                    f"β€” {relevance}{conf_str}"
                )

        tests = dx.get("confirmatory_tests", [])
        if tests:
            out.append(f"**Recommended Tests:** {', '.join(tests[:4])}")

    # ── Devil's Advocate ─────────────────────────────────────────────────
    out.append("\n## 🎭 Devil's Advocate Analysis")
    challenges = (reasoning_result.get("devils_advocate") or {}).get("challenges", [])
    if not challenges:
        out.append("*Not available.*")
    for ch in challenges[:4]:
        cond = ch.get("condition", "")
        if not cond:
            continue
        out.append(f"\n**{cond}**")
        if ch.get("contradicting_evidence"):
            out.append(f"- ⚠️ Counter-evidence: {ch['contradicting_evidence'][:200]}")
        if ch.get("missed_critical"):
            out.append(f"- 🚨 Don't miss: {ch['missed_critical'][:200]}")

    # ── Drug interactions ────────────────────────────────────────────────
    interactions = drug_interactions.get("interactions", [])
    if interactions:
        out.append("\n## πŸ’Š Drug Interaction Alerts")
        for inter in interactions[:5]:
            sev = inter.get("severity", "Unknown")
            icon = _SEVERITY_EMOJI.get(sev.lower(), "βšͺ")
            drugs = " ↔ ".join(inter.get("drugs", []))
            desc = inter.get("description", "")[:180]
            out.append(f"- {icon} **{sev}**  |  {drugs}  |  {desc}")

    # ── Footer ───────────────────────────────────────────────────────────
    out.append("\n---")
    out.append(
        "*MedReason-RAG is an open-source research prototype. "
        "Evidence is retrieved live from PubMed Open Access. "
        "Outputs are for educational demonstration only.*"
    )

    return "\n".join(out)