File size: 3,431 Bytes
08a811f
 
 
 
 
ad9e267
08a811f
 
 
 
 
 
 
 
ad9e267
08a811f
 
 
 
 
ad9e267
08a811f
ad9e267
08a811f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ad9e267
08a811f
ad9e267
08a811f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ad9e267
08a811f
 
 
 
 
ba2715f
 
08a811f
 
 
 
ad9e267
08a811f
 
 
 
 
ad9e267
 
 
 
08a811f
 
ad9e267
08a811f
 
 
 
 
ad9e267
08a811f
 
 
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

from typing import Dict, List, Literal, NotRequired, Optional, TypedDict


class LabResult(TypedDict, total=False):
    """A single lab value with optional reference range and flag."""
    name: str
    value: str
    unit: NotRequired[Optional[str]]
    reference_range: NotRequired[Optional[str]]
    flag: NotRequired[Optional[Literal["low", "normal", "high", "critical"]]]


class MICDatum(TypedDict, total=False):
    """A single MIC measurement for one organism–antibiotic pair."""
    organism: str
    antibiotic: str
    mic_value: str
    mic_unit: NotRequired[Optional[str]]
    interpretation: NotRequired[Optional[Literal["S", "I", "R"]]]
    breakpoint_source: NotRequired[Optional[str]]  # e.g. "EUCAST v16.0"
    year: NotRequired[Optional[int]]
    site: NotRequired[Optional[str]]  # e.g. "blood", "urine"


class Recommendation(TypedDict, total=False):
    """Final clinical recommendation assembled by Agent 4."""
    primary_antibiotic: Optional[str]
    backup_antibiotic: NotRequired[Optional[str]]
    dose: Optional[str]
    route: Optional[str]
    frequency: Optional[str]
    duration: Optional[str]
    rationale: Optional[str]
    references: NotRequired[List[str]]
    safety_alerts: NotRequired[List[str]]


class InfectionState(TypedDict, total=False):
    """
    Shared state object passed between all agents in the pipeline.

    All keys are optional so each agent only needs to populate its own outputs.
    """

    # Patient identity & demographics
    patient_id: NotRequired[Optional[str]]
    age_years: NotRequired[Optional[float]]
    sex: NotRequired[Optional[Literal["male", "female", "other", "unknown"]]]
    weight_kg: NotRequired[Optional[float]]
    height_cm: NotRequired[Optional[float]]

    # Clinical context
    suspected_source: NotRequired[Optional[str]]  # e.g. "community UTI"
    comorbidities: NotRequired[List[str]]
    medications: NotRequired[List[str]]
    allergies: NotRequired[List[str]]
    infection_site: NotRequired[Optional[str]]
    country_or_region: NotRequired[Optional[str]]

    # Renal function & vitals
    serum_creatinine_mg_dl: NotRequired[Optional[float]]
    creatinine_clearance_ml_min: NotRequired[Optional[float]]
    vitals: NotRequired[Dict[str, str]]  # flexible key/value, e.g. {"BP": "120/80"}

    # Lab data & MICs
    labs_raw_text: NotRequired[Optional[str]]   # raw OCR or pasted text
    labs_image_bytes: NotRequired[Optional[bytes]]  # uploaded image (PNG/JPG/TIFF) for vision model
    labs_parsed: NotRequired[List[LabResult]]
    mic_data: NotRequired[List[MICDatum]]
    mic_trend_summary: NotRequired[Optional[str]]

    # Routing flags set by agents
    stage: NotRequired[Literal["empirical", "targeted"]]
    route_to_vision: NotRequired[bool]
    route_to_trend_analyst: NotRequired[bool]

    # Agent outputs
    intake_notes: NotRequired[Optional[str]]       # Agent 1
    vision_notes: NotRequired[Optional[str]]       # Agent 2
    trend_notes: NotRequired[Optional[str]]        # Agent 3
    pharmacology_notes: NotRequired[Optional[str]] # Agent 4
    recommendation: NotRequired[Optional[Recommendation]]

    # RAG context & safety
    rag_context: NotRequired[Optional[str]]
    guideline_sources: NotRequired[List[str]]
    breakpoint_sources: NotRequired[List[str]]
    safety_warnings: NotRequired[List[str]]

    # Diagnostics
    errors: NotRequired[List[str]]
    debug_log: NotRequired[List[str]]