iints-sdk-python35 1.5.9__tar.gz → 1.5.10__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {iints_sdk_python35-1.5.9/src/iints_sdk_python35.egg-info → iints_sdk_python35-1.5.10}/PKG-INFO +5 -5
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/README.md +3 -3
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/pyproject.toml +2 -2
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/__init__.py +1 -1
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/ai/__init__.py +14 -1
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/ai/assistant.py +10 -2
- iints_sdk_python35-1.5.10/src/iints/ai/backends/mistral_api.py +46 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/ai/cli.py +28 -1
- iints_sdk_python35-1.5.10/src/iints/ai/model_catalog.py +174 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/analysis/reporting.py +37 -19
- iints_sdk_python35-1.5.10/src/iints/analysis/run_quality.py +179 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/cli/cli.py +1113 -47
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/core/patient/bergman_model.py +93 -18
- iints_sdk_python35-1.5.10/src/iints/core/patient/hovorka_model.py +432 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/core/patient/models.py +53 -7
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/core/patient/patient_factory.py +12 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/core/simulator.py +44 -13
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/data/realism_dashboard.py +2 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/data/realism_validator.py +185 -7
- iints_sdk_python35-1.5.10/src/iints/live_patient/fpga.py +972 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/presets/presets.json +116 -52
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/validation/schemas.py +17 -1
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/visualization/cockpit.py +44 -20
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10/src/iints_sdk_python35.egg-info}/PKG-INFO +5 -5
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints_sdk_python35.egg-info/SOURCES.txt +3 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints_sdk_python35.egg-info/requires.txt +1 -1
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/tests/test_cli_demo_live.py +48 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/tests/test_cli_edge_runtime.py +87 -0
- iints_sdk_python35-1.5.10/tests/test_cli_fpga.py +139 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/tests/test_cli_onboarding.py +37 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/tests/test_cli_research_workflows.py +23 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/tests/test_presets_realism.py +44 -1
- iints_sdk_python35-1.5.9/src/iints/ai/backends/mistral_api.py +0 -17
- iints_sdk_python35-1.5.9/src/iints/ai/model_catalog.py +0 -55
- iints_sdk_python35-1.5.9/src/iints/analysis/run_quality.py +0 -91
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/LICENSE +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/LICENSE-MIT-IINTS-LEGACY +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/NOTICE +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/setup.cfg +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/ai/backends/__init__.py +1 -1
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/ai/backends/base.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/ai/backends/ollama.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/ai/mdmp_guard.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/ai/prepare.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/ai/prompts.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/analysis/__init__.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/analysis/algorithm_xray.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/analysis/baseline.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/analysis/booth_demo.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/analysis/carelink_workbench.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/analysis/clinical_benchmark.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/analysis/clinical_metrics.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/analysis/clinical_tir_analyzer.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/analysis/diabetes_metrics.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/analysis/edge_efficiency.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/analysis/edge_performance_monitor.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/analysis/eucys_results.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/analysis/evidence_bundle.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/analysis/explainability.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/analysis/explainable_ai.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/analysis/hardware_benchmark.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/analysis/metrics.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/analysis/population_report.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/analysis/poster.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/analysis/safety_index.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/analysis/safety_visualizer.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/analysis/sensor_filtering.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/analysis/study_analysis.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/analysis/study_engine.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/analysis/study_experiment.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/analysis/study_poster.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/analysis/study_protocol.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/analysis/validator.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/api/__init__.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/api/base_algorithm.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/api/registry.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/api/template_algorithm.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/assets/iints_logo.png +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/cli/__init__.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/cli/patient_cli.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/core/__init__.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/core/algorithms/__init__.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/core/algorithms/battle_runner.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/core/algorithms/clinical_baseline.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/core/algorithms/correction_bolus.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/core/algorithms/discovery.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/core/algorithms/fixed_basal_bolus.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/core/algorithms/hybrid_algorithm.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/core/algorithms/imitation_controller.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/core/algorithms/lstm_algorithm.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/core/algorithms/mock_algorithms.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/core/algorithms/neural_controller.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/core/algorithms/pid_controller.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/core/algorithms/standard_pump_algo.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/core/device.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/core/device_manager.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/core/devices/__init__.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/core/devices/models.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/core/patient/__init__.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/core/patient/profile.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/core/physiology_variation.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/core/safety/__init__.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/core/safety/config.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/core/safety/input_validator.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/core/safety/supervisor.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/core/simulation/__init__.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/core/simulation/scenario_parser.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/core/supervisor.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/data/__init__.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/data/adapter.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/data/certify.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/data/column_mapper.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/data/contracts.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/data/datasets.json +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/data/demo/__init__.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/data/demo/demo_cgm.csv +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/data/evidence.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/data/guardians.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/data/importer.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/data/ingestor.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/data/mdmp_visualizer.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/data/medtronic_live.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/data/nightscout.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/data/physiology_residual_profiles.json +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/data/quality_checker.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/data/realism_governance.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/data/realism_reference.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/data/realism_references.json +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/data/registry.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/data/research_catalog.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/data/runner.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/data/study_corruption.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/data/synthetic_mirror.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/data/tidepool.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/data/universal_parser.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/data/virtual_patients/clinic_safe_baseline.yaml +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/data/virtual_patients/clinic_safe_hyper_challenge.yaml +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/data/virtual_patients/clinic_safe_hypo_prone.yaml +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/data/virtual_patients/clinic_safe_midnight.yaml +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/data/virtual_patients/clinic_safe_pizza.yaml +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/data/virtual_patients/clinic_safe_stress_meal.yaml +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/data/virtual_patients/default_patient.yaml +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/data/virtual_patients/patient_559_config.yaml +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/data/virtual_patients/reference_azt1d_t1d.yaml +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/data/virtual_patients/reference_free_living_t1d.yaml +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/data/virtual_patients/reference_hupa_ucm_t1d.yaml +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/demo_assets.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/emulation/__init__.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/emulation/legacy_base.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/emulation/medtronic_780g.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/emulation/omnipod_5.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/emulation/tandem_controliq.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/highlevel.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/jetson/__init__.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/jetson/endurance.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/jetson/research_pipeline.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/learning/__init__.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/learning/autonomous_optimizer.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/learning/learning_system.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/live_patient/__init__.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/live_patient/api.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/live_patient/daemon.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/live_patient/edge_benchmark.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/live_patient/edge_ops.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/live_patient/long_study.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/live_patient/medtronic_direct.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/live_patient/pico_pump.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/live_patient/runtime.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/live_patient/service_export.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/live_patient/uno_q.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/mdmp/__init__.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/mdmp/backend.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/mdmp/eu_ai_pact.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/metrics.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/population/__init__.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/population/generator.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/population/runner.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/presets/__init__.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/presets/evidence_sources.yaml +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/presets/forecast_calibration_profiles.yaml +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/presets/golden_benchmark.yaml +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/presets/safety_contract_default.yaml +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/presets/validation_profiles.yaml +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/research/__init__.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/research/audit.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/research/calibration_gate.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/research/config.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/research/control.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/research/control_eval.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/research/data_blend.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/research/dataset.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/research/evaluation.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/research/local_ai.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/research/local_ai_gate.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/research/losses.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/research/metrics.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/research/model_registry.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/research/neural_control.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/research/predictor.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/scenarios/__init__.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/scenarios/generator.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/scenarios/study_pack.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/templates/__init__.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/templates/default_algorithm.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/templates/demos/__init__.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/templates/demos/live_stage_demo.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/templates/pico_pump/README.md +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/templates/pico_pump/code.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/templates/pico_pump/serial_protocol.txt +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/templates/scenarios/__init__.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/templates/scenarios/chaos_insulin_stacking.json +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/templates/scenarios/chaos_runaway_ai.json +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/templates/scenarios/example_scenario.json +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/templates/scenarios/exercise_stress.json +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/templates/uno_q/README.md +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/templates/uno_q/iints_supervisor_bridge.ino +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/utils/__init__.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/utils/csv_safety.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/utils/plotting.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/utils/run_io.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/utils/url_safety.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/validation/__init__.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/validation/golden.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/validation/replay.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/validation/run_doctor.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/validation/run_validation.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/validation/safety_contract.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/visualization/__init__.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints/visualization/uncertainty_cloud.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints_sdk_python35.egg-info/dependency_links.txt +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints_sdk_python35.egg-info/entry_points.txt +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/iints_sdk_python35.egg-info/top_level.txt +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/mdmp_ai/__init__.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/mdmp_ai/lineage.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/mdmp_core/__init__.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/mdmp_core/audit.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/mdmp_core/bias_hooks.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/mdmp_core/bundle.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/mdmp_core/certification.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/mdmp_core/cli.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/mdmp_core/compare.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/mdmp_core/conformance.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/mdmp_core/contracts.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/mdmp_core/crypto.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/mdmp_core/data/conformance/vectors/delegation.json +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/mdmp_core/data/conformance/vectors/fingerprint.json +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/mdmp_core/data/conformance/vectors/grading.json +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/mdmp_core/data/conformance/vectors/signing.json +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/mdmp_core/delegate.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/mdmp_core/diffing.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/mdmp_core/drift.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/mdmp_core/exceptions.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/mdmp_core/fingerprint.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/mdmp_core/fingerprint_store.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/mdmp_core/hf.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/mdmp_core/keys/mdmp_pub_v1.pem +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/mdmp_core/llm_provenance.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/mdmp_core/migrate.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/mdmp_core/policy.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/mdmp_core/prov.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/mdmp_core/registry.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/mdmp_core/runner.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/mdmp_core/schema_export.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/mdmp_core/synthetic.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/mdmp_core/trust.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/mdmp_core/visualizer.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/mdmp_flavors/__init__.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/mdmp_integrations/__init__.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/mdmp_integrations/dvc.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/mdmp_integrations/mlflow.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/src/mdmp_integrations/wandb.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/tests/test_bergman.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/tests/test_ci_governance.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/tests/test_cli_algorithm_loading.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/tests/test_cli_booth_demo.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/tests/test_cli_carelink_workbench.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/tests/test_cli_cloud_import_security.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/tests/test_cli_demo_export.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/tests/test_cli_expo_tools.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/tests/test_cli_patient_runtime.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/tests/test_cli_poster.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/tests/test_cli_run_summary.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/tests/test_install_doctor.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/tests/test_jetson_endurance.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/tests/test_physiology_variation.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/tests/test_plugin_system.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/tests/test_population.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/tests/test_research_realism_tools.py +0 -0
- {iints_sdk_python35-1.5.9 → iints_sdk_python35-1.5.10}/tests/test_simulator_calibration.py +0 -0
{iints_sdk_python35-1.5.9/src/iints_sdk_python35.egg-info → iints_sdk_python35-1.5.10}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: iints-sdk-python35
|
|
3
|
-
Version: 1.5.
|
|
3
|
+
Version: 1.5.10
|
|
4
4
|
Summary: A pre-clinical Edge-AI SDK for diabetes management validation.
|
|
5
5
|
Author-email: Rune Bobbaers <rune.bobbaers@gmail.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -18,7 +18,7 @@ Description-Content-Type: text/markdown
|
|
|
18
18
|
License-File: LICENSE
|
|
19
19
|
License-File: NOTICE
|
|
20
20
|
License-File: LICENSE-MIT-IINTS-LEGACY
|
|
21
|
-
Requires-Dist: fastapi
|
|
21
|
+
Requires-Dist: fastapi!=0.136.3,<1.0.0,>=0.115.0
|
|
22
22
|
Requires-Dist: numpy<3.0.0,>=1.24.0
|
|
23
23
|
Requires-Dist: pandas<3.0.0,>=2.0.0
|
|
24
24
|
Requires-Dist: pydantic<3.0.0,>=2.0.0
|
|
@@ -117,13 +117,13 @@ Full documentation: [python35.github.io/IINTS-SDK](https://python35.github.io/II
|
|
|
117
117
|
|
|
118
118
|
## Live Demo
|
|
119
119
|
|
|
120
|
-
For a Zoom call, jury walkthrough, or sponsor demo where you want
|
|
120
|
+
For a Zoom call, jury walkthrough, or sponsor demo where you want the story first and code as proof:
|
|
121
121
|
|
|
122
122
|
```bash
|
|
123
|
-
iints demo
|
|
123
|
+
iints demo eucys --output-dir results/live_demo
|
|
124
124
|
```
|
|
125
125
|
|
|
126
|
-
|
|
126
|
+
Use `iints demo doctor` for clinical feedback conversations and `iints demo booth` for public digital-patient demos.
|
|
127
127
|
|
|
128
128
|
---
|
|
129
129
|
|
|
@@ -50,13 +50,13 @@ Full documentation: [python35.github.io/IINTS-SDK](https://python35.github.io/II
|
|
|
50
50
|
|
|
51
51
|
## Live Demo
|
|
52
52
|
|
|
53
|
-
For a Zoom call, jury walkthrough, or sponsor demo where you want
|
|
53
|
+
For a Zoom call, jury walkthrough, or sponsor demo where you want the story first and code as proof:
|
|
54
54
|
|
|
55
55
|
```bash
|
|
56
|
-
iints demo
|
|
56
|
+
iints demo eucys --output-dir results/live_demo
|
|
57
57
|
```
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
Use `iints demo doctor` for clinical feedback conversations and `iints demo booth` for public digital-patient demos.
|
|
60
60
|
|
|
61
61
|
---
|
|
62
62
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "iints-sdk-python35"
|
|
7
|
-
version = "1.5.
|
|
7
|
+
version = "1.5.10"
|
|
8
8
|
authors = [
|
|
9
9
|
{ name="Rune Bobbaers", email="rune.bobbaers@gmail.com" },
|
|
10
10
|
]
|
|
@@ -24,7 +24,7 @@ classifiers = [
|
|
|
24
24
|
"Development Status :: 5 - Production/Stable",
|
|
25
25
|
]
|
|
26
26
|
dependencies = [
|
|
27
|
-
"fastapi>=0.115.0
|
|
27
|
+
"fastapi>=0.115.0,!=0.136.3,<1.0.0",
|
|
28
28
|
"numpy>=1.24.0,<3.0.0",
|
|
29
29
|
"pandas>=2.0.0,<3.0.0",
|
|
30
30
|
"pydantic>=2.0.0,<3.0.0",
|
|
@@ -11,7 +11,7 @@ except ImportError: # pragma: no cover - Python < 3.8 fallback
|
|
|
11
11
|
try:
|
|
12
12
|
__version__ = version("iints-sdk-python35")
|
|
13
13
|
except PackageNotFoundError: # pragma: no cover - source tree fallback
|
|
14
|
-
__version__ = "1.5.
|
|
14
|
+
__version__ = "1.5.10"
|
|
15
15
|
|
|
16
16
|
# Note to developers: this SDK is currently maintained by a single author.
|
|
17
17
|
# Please report bugs via GitHub issues and feel free to contribute fixes via PRs.
|
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
from .assistant import AIResponse, IINTSAssistant
|
|
2
2
|
from .backends import DEFAULT_MINISTRAL_MODEL, DEFAULT_OLLAMA_HOST, OllamaBackend
|
|
3
3
|
from .mdmp_guard import GuardResult, MDMPGuard
|
|
4
|
-
from .model_catalog import
|
|
4
|
+
from .model_catalog import (
|
|
5
|
+
DEFAULT_MISTRAL_API_MODEL,
|
|
6
|
+
DEFAULT_MISTRAL_API_REASONING_EFFORT,
|
|
7
|
+
LocalMistralModelProfile,
|
|
8
|
+
MistralAPIMigrationProfile,
|
|
9
|
+
list_local_mistral_models,
|
|
10
|
+
list_mistral_api_migrations,
|
|
11
|
+
migrate_mistral_api_model,
|
|
12
|
+
)
|
|
5
13
|
from .prepare import prepare_ai_ready_artifacts
|
|
6
14
|
|
|
7
15
|
__all__ = [
|
|
@@ -12,7 +20,12 @@ __all__ = [
|
|
|
12
20
|
"OllamaBackend",
|
|
13
21
|
"GuardResult",
|
|
14
22
|
"MDMPGuard",
|
|
23
|
+
"DEFAULT_MISTRAL_API_MODEL",
|
|
24
|
+
"DEFAULT_MISTRAL_API_REASONING_EFFORT",
|
|
15
25
|
"LocalMistralModelProfile",
|
|
26
|
+
"MistralAPIMigrationProfile",
|
|
16
27
|
"list_local_mistral_models",
|
|
28
|
+
"list_mistral_api_migrations",
|
|
29
|
+
"migrate_mistral_api_model",
|
|
17
30
|
"prepare_ai_ready_artifacts",
|
|
18
31
|
]
|
|
@@ -82,12 +82,20 @@ class IINTSAssistant:
|
|
|
82
82
|
ollama_backend.ensure_model_ready()
|
|
83
83
|
return local_backend
|
|
84
84
|
if requested == "api":
|
|
85
|
-
api_backend: CompletionBackend = MistralAPIBackend()
|
|
85
|
+
api_backend: CompletionBackend = MistralAPIBackend(model_name=model)
|
|
86
86
|
if api_backend.available():
|
|
87
87
|
return api_backend
|
|
88
|
+
api_model = getattr(api_backend, "model_name", "mistral-small-latest")
|
|
89
|
+
api_reasoning = getattr(api_backend, "reasoning_effort", None)
|
|
90
|
+
reasoning_hint = (
|
|
91
|
+
f" with reasoning_effort='{api_reasoning}'"
|
|
92
|
+
if isinstance(api_reasoning, str) and api_reasoning.strip()
|
|
93
|
+
else ""
|
|
94
|
+
)
|
|
88
95
|
raise RuntimeError(
|
|
89
96
|
"Cloud API fallback is not enabled in this SDK build yet. "
|
|
90
|
-
"Use mode='local' with Ollama
|
|
97
|
+
"Use mode='local' with Ollama, or configure an external Mistral client with "
|
|
98
|
+
f"`{api_model}`{reasoning_hint}."
|
|
91
99
|
)
|
|
92
100
|
raise ValueError(f"Unsupported AI mode: {mode}")
|
|
93
101
|
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from ..model_catalog import (
|
|
4
|
+
DEFAULT_MISTRAL_API_MODEL,
|
|
5
|
+
DEFAULT_MISTRAL_API_REASONING_EFFORT,
|
|
6
|
+
migrate_mistral_api_model,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class MistralAPIBackend:
|
|
11
|
+
backend_name = "mistral_api"
|
|
12
|
+
|
|
13
|
+
def __init__(
|
|
14
|
+
self,
|
|
15
|
+
*,
|
|
16
|
+
model_name: str = DEFAULT_MISTRAL_API_MODEL,
|
|
17
|
+
reasoning_effort: str | None = DEFAULT_MISTRAL_API_REASONING_EFFORT,
|
|
18
|
+
**kwargs,
|
|
19
|
+
) -> None:
|
|
20
|
+
migrated_model, migrated_reasoning, migrated = migrate_mistral_api_model(model_name)
|
|
21
|
+
self.requested_model_name = model_name
|
|
22
|
+
self.model_name = migrated_model
|
|
23
|
+
self.reasoning_effort = migrated_reasoning if migrated_reasoning is not None else reasoning_effort
|
|
24
|
+
self.model_was_migrated = migrated
|
|
25
|
+
|
|
26
|
+
def available(self) -> bool:
|
|
27
|
+
return False
|
|
28
|
+
|
|
29
|
+
def complete(self, *, system_prompt: str, user_prompt: str) -> str:
|
|
30
|
+
migration_hint = (
|
|
31
|
+
f" Requested deprecated model '{self.requested_model_name}' was mapped to "
|
|
32
|
+
f"'{self.model_name}'."
|
|
33
|
+
if self.model_was_migrated
|
|
34
|
+
else ""
|
|
35
|
+
)
|
|
36
|
+
reasoning_hint = (
|
|
37
|
+
f" Default Mistral reasoning_effort is '{self.reasoning_effort}'."
|
|
38
|
+
if self.reasoning_effort
|
|
39
|
+
else ""
|
|
40
|
+
)
|
|
41
|
+
raise RuntimeError(
|
|
42
|
+
"Cloud fallback is not enabled in this SDK build yet. "
|
|
43
|
+
"Use mode='local' with Ollama for the open Ministral 3 model, or configure "
|
|
44
|
+
f"your external Mistral client for '{self.model_name}'."
|
|
45
|
+
f"{reasoning_hint}{migration_hint}"
|
|
46
|
+
)
|
|
@@ -12,7 +12,13 @@ from typing_extensions import Annotated
|
|
|
12
12
|
|
|
13
13
|
from .assistant import AIResponse, IINTSAssistant
|
|
14
14
|
from .backends import DEFAULT_MINISTRAL_MODEL, OllamaBackend
|
|
15
|
-
from .model_catalog import
|
|
15
|
+
from .model_catalog import (
|
|
16
|
+
DEFAULT_MISTRAL_API_MODEL,
|
|
17
|
+
DEFAULT_MISTRAL_API_REASONING_EFFORT,
|
|
18
|
+
STRONG_MISTRAL_API_MODEL,
|
|
19
|
+
list_local_mistral_models,
|
|
20
|
+
list_mistral_api_migrations,
|
|
21
|
+
)
|
|
16
22
|
from .prepare import prepare_ai_ready_artifacts
|
|
17
23
|
|
|
18
24
|
|
|
@@ -183,10 +189,31 @@ def models() -> None:
|
|
|
183
189
|
)
|
|
184
190
|
|
|
185
191
|
console.print(table)
|
|
192
|
+
migration_table = Table(title="Mistral Serverless Migration Guide")
|
|
193
|
+
migration_table.add_column("Deprecated", style="yellow", overflow="fold")
|
|
194
|
+
migration_table.add_column("Replacement", style="cyan", no_wrap=True)
|
|
195
|
+
migration_table.add_column("Reasoning")
|
|
196
|
+
migration_table.add_column("Retires")
|
|
197
|
+
migration_table.add_column("Use Case", overflow="fold")
|
|
198
|
+
for migration_profile in list_mistral_api_migrations():
|
|
199
|
+
reasoning = migration_profile.reasoning_effort or "n/a"
|
|
200
|
+
migration_table.add_row(
|
|
201
|
+
", ".join(migration_profile.deprecated_models),
|
|
202
|
+
migration_profile.replacement_model,
|
|
203
|
+
reasoning,
|
|
204
|
+
migration_profile.retirement_date,
|
|
205
|
+
migration_profile.use_case,
|
|
206
|
+
)
|
|
207
|
+
console.print(migration_table)
|
|
186
208
|
console.print(
|
|
187
209
|
"[dim]Tip:[/dim] start with "
|
|
188
210
|
f"`{DEFAULT_MINISTRAL_MODEL}` unless you know your hardware can comfortably run a larger local model."
|
|
189
211
|
)
|
|
212
|
+
console.print(
|
|
213
|
+
"[dim]Serverless:[/dim] use "
|
|
214
|
+
f"`{DEFAULT_MISTRAL_API_MODEL}` with `reasoning_effort={DEFAULT_MISTRAL_API_REASONING_EFFORT}` "
|
|
215
|
+
f"for small reasoning/code tasks, or `{STRONG_MISTRAL_API_MODEL}` for stronger review."
|
|
216
|
+
)
|
|
190
217
|
|
|
191
218
|
|
|
192
219
|
@app.command(name="prepare")
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
|
|
5
|
+
from .backends.ollama import DEFAULT_MINISTRAL_MODEL
|
|
6
|
+
|
|
7
|
+
DEFAULT_MISTRAL_API_MODEL = "mistral-small-latest"
|
|
8
|
+
DEFAULT_MISTRAL_API_REASONING_EFFORT = "high"
|
|
9
|
+
STRONG_MISTRAL_API_MODEL = "mistral-medium-3-5"
|
|
10
|
+
DEFAULT_MISTRAL_OCR_MODEL = "mistral-ocr-latest"
|
|
11
|
+
DEFAULT_MISTRAL_MODERATION_MODEL = "mistral-moderation-2603"
|
|
12
|
+
DEFAULT_MISTRAL_TRANSCRIBE_MODEL = "voxtral-mini-latest"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@dataclass(frozen=True)
|
|
16
|
+
class LocalMistralModelProfile:
|
|
17
|
+
tag: str
|
|
18
|
+
label: str
|
|
19
|
+
approx_download_gb: float
|
|
20
|
+
recommended_system_ram_gb: int
|
|
21
|
+
recommended_vram_gb: int | None
|
|
22
|
+
fit: str
|
|
23
|
+
notes: str
|
|
24
|
+
aliases: tuple[str, ...] = ()
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@dataclass(frozen=True)
|
|
28
|
+
class MistralAPIMigrationProfile:
|
|
29
|
+
deprecated_models: tuple[str, ...]
|
|
30
|
+
replacement_model: str
|
|
31
|
+
reasoning_effort: str | None
|
|
32
|
+
retirement_date: str
|
|
33
|
+
use_case: str
|
|
34
|
+
notes: str
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
LOCAL_MISTRAL_MODEL_PROFILES: tuple[LocalMistralModelProfile, ...] = (
|
|
38
|
+
LocalMistralModelProfile(
|
|
39
|
+
tag="ministral-3:3b",
|
|
40
|
+
label="Ministral 3 3B",
|
|
41
|
+
approx_download_gb=3.0,
|
|
42
|
+
recommended_system_ram_gb=16,
|
|
43
|
+
recommended_vram_gb=6,
|
|
44
|
+
fit="Entry-level laptop / small edge box",
|
|
45
|
+
notes="Best starting point for CPU-only systems or modest GPUs. Fastest option, lowest memory pressure.",
|
|
46
|
+
aliases=("ministral-3:3b",),
|
|
47
|
+
),
|
|
48
|
+
LocalMistralModelProfile(
|
|
49
|
+
tag=DEFAULT_MINISTRAL_MODEL,
|
|
50
|
+
label="Ministral 3 8B",
|
|
51
|
+
approx_download_gb=6.0,
|
|
52
|
+
recommended_system_ram_gb=24,
|
|
53
|
+
recommended_vram_gb=10,
|
|
54
|
+
fit="Balanced desktop / strong laptop",
|
|
55
|
+
notes="Recommended default for most users. Best trade-off between quality, speed, and local memory footprint.",
|
|
56
|
+
aliases=("ministral", "ministral-3", "ministral-3:8b"),
|
|
57
|
+
),
|
|
58
|
+
LocalMistralModelProfile(
|
|
59
|
+
tag="ministral-3:14b",
|
|
60
|
+
label="Ministral 3 14B",
|
|
61
|
+
approx_download_gb=10.0,
|
|
62
|
+
recommended_system_ram_gb=32,
|
|
63
|
+
recommended_vram_gb=16,
|
|
64
|
+
fit="High-end workstation",
|
|
65
|
+
notes="Use when you have plenty of RAM or a strong GPU and want better reasoning depth at the cost of latency.",
|
|
66
|
+
aliases=("ministral-3:14b",),
|
|
67
|
+
),
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
MISTRAL_API_MIGRATION_PROFILES: tuple[MistralAPIMigrationProfile, ...] = (
|
|
72
|
+
MistralAPIMigrationProfile(
|
|
73
|
+
deprecated_models=("devstral-small-2507", "devstral-small-latest"),
|
|
74
|
+
replacement_model=DEFAULT_MISTRAL_API_MODEL,
|
|
75
|
+
reasoning_effort=DEFAULT_MISTRAL_API_REASONING_EFFORT,
|
|
76
|
+
retirement_date="2026-05-31",
|
|
77
|
+
use_case="code and agentic helper",
|
|
78
|
+
notes="Use Mistral Small 4 through the stable latest alias.",
|
|
79
|
+
),
|
|
80
|
+
MistralAPIMigrationProfile(
|
|
81
|
+
deprecated_models=("devstral-medium-2507", "devstral-2512", "devstral-latest"),
|
|
82
|
+
replacement_model=STRONG_MISTRAL_API_MODEL,
|
|
83
|
+
reasoning_effort=DEFAULT_MISTRAL_API_REASONING_EFFORT,
|
|
84
|
+
retirement_date="2026-05-31 / 2026-07-31",
|
|
85
|
+
use_case="strong code and research assistant",
|
|
86
|
+
notes="Use Mistral Medium 3.5 for higher-complexity code/research review.",
|
|
87
|
+
),
|
|
88
|
+
MistralAPIMigrationProfile(
|
|
89
|
+
deprecated_models=("magistral-small-2509",),
|
|
90
|
+
replacement_model=DEFAULT_MISTRAL_API_MODEL,
|
|
91
|
+
reasoning_effort=DEFAULT_MISTRAL_API_REASONING_EFFORT,
|
|
92
|
+
retirement_date="2026-07-31",
|
|
93
|
+
use_case="small reasoning",
|
|
94
|
+
notes="Mistral Small 4 now supports adjustable reasoning.",
|
|
95
|
+
),
|
|
96
|
+
MistralAPIMigrationProfile(
|
|
97
|
+
deprecated_models=("magistral-medium-2509", "magistral-medium-latest"),
|
|
98
|
+
replacement_model=STRONG_MISTRAL_API_MODEL,
|
|
99
|
+
reasoning_effort=DEFAULT_MISTRAL_API_REASONING_EFFORT,
|
|
100
|
+
retirement_date="2026-07-31",
|
|
101
|
+
use_case="medium reasoning",
|
|
102
|
+
notes="Mistral Medium 3.5 supports adjustable reasoning for harder tasks.",
|
|
103
|
+
),
|
|
104
|
+
MistralAPIMigrationProfile(
|
|
105
|
+
deprecated_models=(
|
|
106
|
+
"mistral-large-2411",
|
|
107
|
+
"pixtral-large-2411",
|
|
108
|
+
"mistral-medium-2505",
|
|
109
|
+
"mistral-medium-2508",
|
|
110
|
+
),
|
|
111
|
+
replacement_model=STRONG_MISTRAL_API_MODEL,
|
|
112
|
+
reasoning_effort=DEFAULT_MISTRAL_API_REASONING_EFFORT,
|
|
113
|
+
retirement_date="2026-05-31 / 2026-08-31",
|
|
114
|
+
use_case="general strong cloud model",
|
|
115
|
+
notes="Medium 3.5 is the current stronger general-purpose replacement.",
|
|
116
|
+
),
|
|
117
|
+
MistralAPIMigrationProfile(
|
|
118
|
+
deprecated_models=("mistral-small-2506",),
|
|
119
|
+
replacement_model=DEFAULT_MISTRAL_API_MODEL,
|
|
120
|
+
reasoning_effort=DEFAULT_MISTRAL_API_REASONING_EFFORT,
|
|
121
|
+
retirement_date="2026-07-31",
|
|
122
|
+
use_case="small general cloud model",
|
|
123
|
+
notes="Use the Mistral Small 4 latest alias.",
|
|
124
|
+
),
|
|
125
|
+
MistralAPIMigrationProfile(
|
|
126
|
+
deprecated_models=("open-mistral-nemo-2407",),
|
|
127
|
+
replacement_model="ministral-8b-2512",
|
|
128
|
+
reasoning_effort=None,
|
|
129
|
+
retirement_date="2026-07-31",
|
|
130
|
+
use_case="small/low-cost serverless model",
|
|
131
|
+
notes="Serverless replacement for Nemo. Local SDK defaults still use Ollama `ministral-3:8b`.",
|
|
132
|
+
),
|
|
133
|
+
MistralAPIMigrationProfile(
|
|
134
|
+
deprecated_models=("mistral-ocr-2505",),
|
|
135
|
+
replacement_model=DEFAULT_MISTRAL_OCR_MODEL,
|
|
136
|
+
reasoning_effort=None,
|
|
137
|
+
retirement_date="2026-05-31",
|
|
138
|
+
use_case="OCR",
|
|
139
|
+
notes="Use OCR 3 through the latest alias.",
|
|
140
|
+
),
|
|
141
|
+
MistralAPIMigrationProfile(
|
|
142
|
+
deprecated_models=("mistral-moderation-2411", "mistral-moderation-latest"),
|
|
143
|
+
replacement_model=DEFAULT_MISTRAL_MODERATION_MODEL,
|
|
144
|
+
reasoning_effort=None,
|
|
145
|
+
retirement_date="2026-06-30",
|
|
146
|
+
use_case="moderation",
|
|
147
|
+
notes="Use Mistral Moderation 2.",
|
|
148
|
+
),
|
|
149
|
+
MistralAPIMigrationProfile(
|
|
150
|
+
deprecated_models=("voxtral-mini-2507",),
|
|
151
|
+
replacement_model=DEFAULT_MISTRAL_TRANSCRIBE_MODEL,
|
|
152
|
+
reasoning_effort=None,
|
|
153
|
+
retirement_date="2026-05-31",
|
|
154
|
+
use_case="audio transcription",
|
|
155
|
+
notes="Use Voxtral Mini Transcribe 2.0 through the latest alias.",
|
|
156
|
+
),
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def list_local_mistral_models() -> list[LocalMistralModelProfile]:
|
|
161
|
+
return list(LOCAL_MISTRAL_MODEL_PROFILES)
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def list_mistral_api_migrations() -> list[MistralAPIMigrationProfile]:
|
|
165
|
+
return list(MISTRAL_API_MIGRATION_PROFILES)
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def migrate_mistral_api_model(model_name: str) -> tuple[str, str | None, bool]:
|
|
169
|
+
requested = model_name.strip()
|
|
170
|
+
requested_key = requested.lower()
|
|
171
|
+
for profile in MISTRAL_API_MIGRATION_PROFILES:
|
|
172
|
+
if requested_key in {model.lower() for model in profile.deprecated_models}:
|
|
173
|
+
return profile.replacement_model, profile.reasoning_effort, True
|
|
174
|
+
return requested, None, False
|
|
@@ -187,22 +187,36 @@ class ClinicalReportGenerator:
|
|
|
187
187
|
p75 = q[0.75].to_numpy(dtype=float)
|
|
188
188
|
p95 = q[0.95].to_numpy(dtype=float)
|
|
189
189
|
|
|
190
|
+
import seaborn as sns
|
|
191
|
+
|
|
192
|
+
sns.set_style("whitegrid")
|
|
193
|
+
|
|
190
194
|
plt.figure(figsize=(10, 4.2))
|
|
191
|
-
plt.fill_between(x, p05, p95, color="#
|
|
192
|
-
plt.fill_between(x, p25, p75, color="#
|
|
193
|
-
plt.plot(x, p50, color="#
|
|
194
|
-
plt.axhspan(target_low, target_high, color="#
|
|
195
|
-
plt.axhline(target_low, color="#
|
|
196
|
-
plt.axhline(target_high, color="#
|
|
195
|
+
plt.fill_between(x, p05, p95, color="#E0E0E0", label="5-95%", linewidth=0)
|
|
196
|
+
plt.fill_between(x, p25, p75, color="#A6A6A6", label="25-75%", linewidth=0)
|
|
197
|
+
plt.plot(x, p50, color="#000000", linewidth=2.5, label="Median")
|
|
198
|
+
plt.axhspan(target_low, target_high, color="#2E7D32", alpha=0.08)
|
|
199
|
+
plt.axhline(target_low, color="#424242", linestyle="--", linewidth=1.0)
|
|
200
|
+
plt.axhline(target_high, color="#424242", linestyle="--", linewidth=1.0)
|
|
201
|
+
|
|
202
|
+
ax = plt.gca()
|
|
203
|
+
ax.spines['top'].set_visible(False)
|
|
204
|
+
ax.spines['right'].set_visible(False)
|
|
205
|
+
ax.spines['left'].set_color('#333333')
|
|
206
|
+
ax.spines['bottom'].set_color('#333333')
|
|
207
|
+
|
|
197
208
|
plt.xlim(0, 24)
|
|
198
209
|
ymax = max(350.0, float(np.nanmax(p95)) + 20.0)
|
|
199
210
|
plt.ylim(40, ymax)
|
|
200
211
|
plt.xticks([0, 3, 6, 9, 12, 15, 18, 21, 24], ["12a", "3a", "6a", "9a", "12p", "3p", "6p", "9p", "12a"])
|
|
201
|
-
plt.ylabel("mg/dL")
|
|
202
|
-
plt.title("Ambulatory Glucose Profile (AGP-style modal day)")
|
|
203
|
-
|
|
212
|
+
plt.ylabel("mg/dL", fontweight="bold")
|
|
213
|
+
plt.title("Ambulatory Glucose Profile (AGP-style modal day)", fontweight="bold")
|
|
214
|
+
|
|
215
|
+
ax.grid(True, axis="y", alpha=0.3, linestyle="-", color="#CCCCCC")
|
|
216
|
+
ax.grid(False, axis="x")
|
|
217
|
+
|
|
204
218
|
plt.tight_layout()
|
|
205
|
-
plt.savefig(output_path, dpi=
|
|
219
|
+
plt.savefig(output_path, dpi=300)
|
|
206
220
|
plt.close()
|
|
207
221
|
|
|
208
222
|
def _plot_daily_profiles(
|
|
@@ -230,23 +244,27 @@ class ClinicalReportGenerator:
|
|
|
230
244
|
daily = df[df["day_index"] == day_id].copy()
|
|
231
245
|
x = daily["minute_of_day"].to_numpy(dtype=float) / 60.0
|
|
232
246
|
y = daily["glucose_actual_mgdl"].to_numpy(dtype=float)
|
|
233
|
-
ax.axhspan(target_low, target_high, color="#
|
|
234
|
-
ax.fill_between(x, target_high, y, where=y > target_high, color="#
|
|
235
|
-
ax.fill_between(x, y, target_low, where=y < target_low, color="#
|
|
236
|
-
ax.plot(x, y, color="#
|
|
247
|
+
ax.axhspan(target_low, target_high, color="#F5F5F5", alpha=1.0)
|
|
248
|
+
ax.fill_between(x, target_high, y, where=y > target_high, color="#FFB300", alpha=0.7)
|
|
249
|
+
ax.fill_between(x, y, target_low, where=y < target_low, color="#D32F2F", alpha=0.7)
|
|
250
|
+
ax.plot(x, y, color="#212121", linewidth=1.2)
|
|
237
251
|
ax.set_xlim(0, 24)
|
|
238
252
|
ax.set_ylim(40, max(260, float(np.nanmax(y)) + 20 if len(y) else 260))
|
|
239
253
|
ax.set_xticks([0, 12, 24])
|
|
240
254
|
ax.set_xticklabels(["12a", "12p", "12a"], fontsize=6)
|
|
241
255
|
ax.set_yticks([])
|
|
242
|
-
ax.set_title(f"Day {int(day_id) + 1}", fontsize=8)
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
256
|
+
ax.set_title(f"Day {int(day_id) + 1}", fontsize=8, fontweight="bold")
|
|
257
|
+
|
|
258
|
+
ax.spines['top'].set_visible(False)
|
|
259
|
+
ax.spines['right'].set_visible(False)
|
|
260
|
+
ax.spines['left'].set_color("#888888")
|
|
261
|
+
ax.spines['left'].set_linewidth(0.5)
|
|
262
|
+
ax.spines['bottom'].set_color("#888888")
|
|
263
|
+
ax.spines['bottom'].set_linewidth(0.5)
|
|
246
264
|
|
|
247
265
|
fig.suptitle("Daily Glucose Profiles", fontsize=12, fontweight="bold")
|
|
248
266
|
fig.tight_layout(rect=(0, 0, 1, 0.92))
|
|
249
|
-
fig.savefig(output_path, dpi=
|
|
267
|
+
fig.savefig(output_path, dpi=300)
|
|
250
268
|
plt.close(fig)
|
|
251
269
|
|
|
252
270
|
@staticmethod
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Any, Dict, Optional
|
|
5
|
+
|
|
6
|
+
import pandas as pd
|
|
7
|
+
|
|
8
|
+
from iints.analysis.safety_visualizer import write_safety_visualizer
|
|
9
|
+
from iints.data.realism_dashboard import write_realism_dashboard
|
|
10
|
+
from iints.data.realism_validator import validate_realism_dataset, write_realism_report
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _series_or_default(df: pd.DataFrame, column: str, default: float = 0.0) -> pd.Series:
|
|
14
|
+
if column not in df.columns:
|
|
15
|
+
return pd.Series([default] * len(df), index=df.index, dtype=float)
|
|
16
|
+
return pd.to_numeric(df[column], errors="coerce").fillna(default).astype(float)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def standardize_simulation_for_realism(results_df: pd.DataFrame) -> pd.DataFrame:
|
|
20
|
+
"""Convert an IINTS results CSV into the generic realism-check schema."""
|
|
21
|
+
if "glucose_actual_mgdl" not in results_df.columns:
|
|
22
|
+
raise ValueError("Realism scoring requires a glucose_actual_mgdl column.")
|
|
23
|
+
|
|
24
|
+
frame = pd.DataFrame(index=results_df.index)
|
|
25
|
+
frame["timestamp"] = _series_or_default(results_df, "time_minutes")
|
|
26
|
+
frame["glucose"] = _series_or_default(results_df, "glucose_actual_mgdl")
|
|
27
|
+
frame["carbs"] = _series_or_default(results_df, "carb_intake_grams")
|
|
28
|
+
frame["insulin"] = _series_or_default(results_df, "delivered_insulin_units")
|
|
29
|
+
return frame
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _auto_realism_reference(realism_frame: pd.DataFrame, requested: str | None) -> str | None:
|
|
33
|
+
"""Use empirical daily references only when the run is actually day-scale."""
|
|
34
|
+
if requested != "auto":
|
|
35
|
+
return requested
|
|
36
|
+
|
|
37
|
+
timestamps = pd.to_numeric(realism_frame.get("timestamp", pd.Series(dtype=float)), errors="coerce").dropna()
|
|
38
|
+
if len(timestamps) < 2:
|
|
39
|
+
return None
|
|
40
|
+
|
|
41
|
+
duration_hours = float((timestamps.max() - timestamps.min()) / 60.0)
|
|
42
|
+
carbs = pd.to_numeric(realism_frame.get("carbs", pd.Series(dtype=float)), errors="coerce").fillna(0.0)
|
|
43
|
+
meal_count = int((carbs >= 10.0).sum())
|
|
44
|
+
if duration_hours >= 18.0 and meal_count >= 3:
|
|
45
|
+
return "free_living_t1d"
|
|
46
|
+
return None
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def _write_run_quality_markdown(
|
|
50
|
+
output_path: Path,
|
|
51
|
+
*,
|
|
52
|
+
run_label: str,
|
|
53
|
+
realism_report: Any,
|
|
54
|
+
selected_reference: str | None,
|
|
55
|
+
reference_selection: str | None,
|
|
56
|
+
) -> Path:
|
|
57
|
+
failed = [check for check in realism_report.checks if check.status == "failed"]
|
|
58
|
+
warnings = [check for check in realism_report.checks if check.status == "warning"]
|
|
59
|
+
lines = [
|
|
60
|
+
f"# IINTS Run Quality Review - {run_label}",
|
|
61
|
+
"",
|
|
62
|
+
"This review is generated automatically to catch physiologically implausible simulation artifacts before a run is used for demos, reports, or AI research.",
|
|
63
|
+
"",
|
|
64
|
+
"## Summary",
|
|
65
|
+
"",
|
|
66
|
+
f"- Verdict: `{realism_report.verdict}`",
|
|
67
|
+
f"- Realism score: `{realism_report.realism_score:.2f}`",
|
|
68
|
+
f"- Reference selection: `{reference_selection}`",
|
|
69
|
+
f"- Applied reference: `{selected_reference or 'none'}`",
|
|
70
|
+
f"- Mean glucose: `{realism_report.metrics.get('mean_glucose_mgdl')} mg/dL`",
|
|
71
|
+
f"- CV: `{realism_report.metrics.get('cv_pct')}%`",
|
|
72
|
+
f"- Max glucose rate: `{realism_report.metrics.get('max_abs_rate_mgdl_per_min')} mg/dL/min`",
|
|
73
|
+
f"- Longest near-flat stretch: `{realism_report.metrics.get('longest_low_motion_minutes')} min`",
|
|
74
|
+
"",
|
|
75
|
+
"## Interpretation",
|
|
76
|
+
"",
|
|
77
|
+
realism_report.summary,
|
|
78
|
+
"",
|
|
79
|
+
]
|
|
80
|
+
if failed or warnings:
|
|
81
|
+
lines.extend(["## Review Items", ""])
|
|
82
|
+
for check in failed + warnings:
|
|
83
|
+
lines.append(f"- `{check.status}` - {check.title}: {check.detail}")
|
|
84
|
+
lines.append("")
|
|
85
|
+
else:
|
|
86
|
+
lines.extend(["## Review Items", "", "- No failed or warning realism checks were detected.", ""])
|
|
87
|
+
|
|
88
|
+
lines.extend([
|
|
89
|
+
"## Check Breakdown",
|
|
90
|
+
"",
|
|
91
|
+
"| Check | Status | Detail |",
|
|
92
|
+
"| --- | --- | --- |",
|
|
93
|
+
])
|
|
94
|
+
for check in realism_report.checks:
|
|
95
|
+
detail = str(check.detail).replace("|", "\\|")
|
|
96
|
+
lines.append(f"| {check.title} | `{check.status}` | {detail} |")
|
|
97
|
+
|
|
98
|
+
lines.extend([
|
|
99
|
+
"",
|
|
100
|
+
"## Research Use Note",
|
|
101
|
+
"",
|
|
102
|
+
"A `likely_realistic` verdict means the trace passes the SDK's plausibility checks. It does not make the SDK a medical device and does not prove clinical validity. For local-AI training or public claims, use external reference profiles and the strict real-data gate.",
|
|
103
|
+
"",
|
|
104
|
+
])
|
|
105
|
+
output_path.write_text("\n".join(lines), encoding="utf-8")
|
|
106
|
+
return output_path
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def write_run_quality_artifacts(
|
|
110
|
+
results_df: pd.DataFrame,
|
|
111
|
+
output_dir: str | Path,
|
|
112
|
+
*,
|
|
113
|
+
run_label: Optional[str] = None,
|
|
114
|
+
safety_report: Optional[Dict[str, Any]] = None,
|
|
115
|
+
realism_reference: Optional[str] = "auto",
|
|
116
|
+
) -> Dict[str, Any]:
|
|
117
|
+
"""Write reviewer-facing quality artifacts for one run.
|
|
118
|
+
|
|
119
|
+
The artifacts are intentionally non-blocking: if realism scoring cannot run
|
|
120
|
+
because a CSV is incomplete, the simulation still completes and a warning is
|
|
121
|
+
returned to the caller.
|
|
122
|
+
"""
|
|
123
|
+
output_path = Path(output_dir)
|
|
124
|
+
output_path.mkdir(parents=True, exist_ok=True)
|
|
125
|
+
label = run_label or output_path.name
|
|
126
|
+
outputs: Dict[str, Any] = {}
|
|
127
|
+
|
|
128
|
+
try:
|
|
129
|
+
realism_frame = standardize_simulation_for_realism(results_df)
|
|
130
|
+
selected_reference = _auto_realism_reference(realism_frame, realism_reference)
|
|
131
|
+
realism_report = validate_realism_dataset(realism_frame, reference=selected_reference)
|
|
132
|
+
realism_json = output_path / "realism_report.json"
|
|
133
|
+
realism_html = output_path / "realism_dashboard.html"
|
|
134
|
+
realism_markdown = output_path / "run_quality_review.md"
|
|
135
|
+
write_realism_report(realism_report, realism_json)
|
|
136
|
+
write_realism_dashboard(
|
|
137
|
+
realism_report,
|
|
138
|
+
realism_frame,
|
|
139
|
+
realism_html,
|
|
140
|
+
title="IINTS Run Realism Review",
|
|
141
|
+
source_label=label,
|
|
142
|
+
)
|
|
143
|
+
_write_run_quality_markdown(
|
|
144
|
+
realism_markdown,
|
|
145
|
+
run_label=label,
|
|
146
|
+
realism_report=realism_report,
|
|
147
|
+
selected_reference=selected_reference,
|
|
148
|
+
reference_selection=realism_reference,
|
|
149
|
+
)
|
|
150
|
+
realism_summary = {
|
|
151
|
+
"verdict": realism_report.verdict,
|
|
152
|
+
"realism_score": realism_report.realism_score,
|
|
153
|
+
"summary": realism_report.summary,
|
|
154
|
+
"reference": selected_reference,
|
|
155
|
+
"reference_selection": realism_reference,
|
|
156
|
+
}
|
|
157
|
+
if safety_report is not None:
|
|
158
|
+
safety_report["realism_review"] = realism_summary
|
|
159
|
+
outputs.update(
|
|
160
|
+
{
|
|
161
|
+
"realism_report_json": str(realism_json),
|
|
162
|
+
"realism_dashboard_html": str(realism_html),
|
|
163
|
+
"run_quality_review_md": str(realism_markdown),
|
|
164
|
+
"realism_review": realism_summary,
|
|
165
|
+
}
|
|
166
|
+
)
|
|
167
|
+
except Exception as exc:
|
|
168
|
+
outputs["realism_warning"] = str(exc)
|
|
169
|
+
|
|
170
|
+
safety_outputs = write_safety_visualizer(
|
|
171
|
+
results_df,
|
|
172
|
+
output_path / "safety_visualizer.html",
|
|
173
|
+
output_json=output_path / "safety_visualizer.json",
|
|
174
|
+
safety_report=safety_report,
|
|
175
|
+
title="IINTS Safety Contract Visualizer",
|
|
176
|
+
)
|
|
177
|
+
outputs["safety_visualizer_html"] = safety_outputs["html"]
|
|
178
|
+
outputs["safety_visualizer_json"] = safety_outputs.get("json")
|
|
179
|
+
return outputs
|