Spaces:
Running on Zero
Running on Zero
| import sys | |
| from pathlib import Path | |
| sys.path.insert(0, str(Path(__file__).resolve().parents[1])) | |
| from src.openbmb_client import EXTRACTION_PROMPT, ExtractionResult | |
| from src.pipeline_trace import build_pipeline_trace, empty_trace_html, trace_hover_js, trace_to_html | |
| from src.report_pipeline import build_health_report | |
| def _sample_extraction() -> ExtractionResult: | |
| return ExtractionResult( | |
| patient={"age": "42y", "age_years": 42.0, "sex": "female", "age_group": "adult"}, | |
| tests=[ | |
| { | |
| "marker": "Hemoglobin", | |
| "value": "11.2", | |
| "unit": "g/dL", | |
| "reference_range": "12.0-16.0", | |
| "status": "low", | |
| "source_text": "Hgb 11.2", | |
| "confidence": 0.95, | |
| }, | |
| { | |
| "marker": "WBC", | |
| "value": "6.5", | |
| "unit": "10^3/uL", | |
| "reference_range": "4.5-11.0", | |
| "status": "normal", | |
| "source_text": "WBC 6.5", | |
| "confidence": 0.9, | |
| }, | |
| ], | |
| notes=["Sample note"], | |
| raw_response='{"tests":[{"marker":"Hemoglobin","value":"11.2"}]}', | |
| request_summary={ | |
| "backend": "test", | |
| "extraction_prompt": EXTRACTION_PROMPT, | |
| "document_parts": 2, | |
| "http_status": 200, | |
| "return_code": 0, | |
| "duration_ms": 842, | |
| "user_message_preview": {"image_count": 1, "text_characters": 120}, | |
| }, | |
| ) | |
| def test_build_pipeline_trace_has_five_steps(): | |
| extraction = _sample_extraction() | |
| report = build_health_report(extraction) | |
| steps = build_pipeline_trace(extraction, report, source_path="/tmp/report.pdf") | |
| assert len(steps) == 5 | |
| assert [step.id for step in steps] == [ | |
| "document_intake", | |
| "vision_extraction", | |
| "schema_normalization", | |
| "knowledge_graph", | |
| "pattern_detection", | |
| ] | |
| def test_extraction_step_includes_full_prompt(): | |
| extraction = _sample_extraction() | |
| report = build_health_report(extraction) | |
| steps = build_pipeline_trace(extraction, report) | |
| extraction_step = steps[1] | |
| assert extraction_step.prompt == EXTRACTION_PROMPT | |
| assert extraction_step.return_code == 0 | |
| assert extraction_step.metadata["http_status"] == 200 | |
| assert extraction_step.metadata["duration_ms"] == 842 | |
| def test_trace_to_html_collapsible_steps(): | |
| extraction = _sample_extraction() | |
| report = build_health_report(extraction) | |
| steps = build_pipeline_trace(extraction, report) | |
| html = trace_to_html(steps, interactive=True) | |
| assert "bte-trace-step" in html | |
| assert html.count("bte-trace-step-collapse") == len(steps) | |
| assert '<details class="bte-trace-step">' not in html | |
| assert "bte-trace-status--complete" not in html | |
| assert "Return code" in html | |
| assert "Full prompt" in html | |
| assert "bte-trace-explanation" in html | |
| assert "Technical details" in html | |
| assert "This step gets your upload ready for the AI." in html | |
| assert "In this run:" in html | |
| assert 'data-interactive="true"' in html | |
| assert "<script" not in html.lower() | |
| def test_completed_steps_include_technical_details(): | |
| extraction = _sample_extraction() | |
| report = build_health_report(extraction) | |
| steps = build_pipeline_trace(extraction, report, source_path="/tmp/report.pdf") | |
| intake = steps[0] | |
| assert intake.technical_details is not None | |
| assert "Backend:" in intake.technical_details | |
| assert "This step gets your upload ready" in intake.summary | |
| def test_empty_trace_html_shows_pending_steps(): | |
| html = empty_trace_html() | |
| assert html.count("bte-trace-step--locked") == 5 | |
| assert '<details class="bte-trace-step">' not in html | |
| assert "bte-trace-status--pending" not in html | |
| assert "Step 1 — Document intake" in html | |
| assert "Step 5 — Cross-marker pattern detection" in html | |
| assert "Waiting for you to upload a lab report." not in html | |
| assert 'data-interactive="false"' in html | |
| def test_trace_hover_js_registers_listeners_once(): | |
| js = trace_hover_js() | |
| assert "__bteTraceHoverInit" in js | |
| assert "OPEN_DELAY_MS" in js | |
| assert "is-open" in js | |
| assert 'panel.dataset.interactive === "true"' in js | |
| assert "<script" not in js.lower() | |
| if __name__ == "__main__": | |
| test_build_pipeline_trace_has_five_steps() | |
| test_extraction_step_includes_full_prompt() | |
| test_trace_to_html_collapsible_steps() | |
| print("test_pipeline_trace: ok") | |