Spaces:
Sleeping
Sleeping
Upload folder using huggingface_hub
Browse files- acde_openenv.egg-info/PKG-INFO +57 -0
- app/environment/core.py +6 -6
- app/environment/validation.py +8 -7
acde_openenv.egg-info/PKG-INFO
CHANGED
|
@@ -11,6 +11,15 @@ Requires-Dist: requests==2.32.3
|
|
| 11 |
Requires-Dist: openai>=2.7.2
|
| 12 |
Requires-Dist: openenv-core
|
| 13 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
# Emergency Routing Simulation (ACDE)
|
| 15 |
|
| 16 |
This project is a simulation environment for emergency ambulance routing.
|
|
@@ -95,6 +104,54 @@ When server mode is running:
|
|
| 95 |
- `POST /step`
|
| 96 |
- `GET /state`
|
| 97 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 98 |
## Installation
|
| 99 |
|
| 100 |
## 1) Prerequisites
|
|
|
|
| 11 |
Requires-Dist: openai>=2.7.2
|
| 12 |
Requires-Dist: openenv-core
|
| 13 |
|
| 14 |
+
---
|
| 15 |
+
title: ACDE OpenEnv
|
| 16 |
+
emoji: "🚑"
|
| 17 |
+
colorFrom: blue
|
| 18 |
+
colorTo: green
|
| 19 |
+
sdk: docker
|
| 20 |
+
pinned: false
|
| 21 |
+
---
|
| 22 |
+
|
| 23 |
# Emergency Routing Simulation (ACDE)
|
| 24 |
|
| 25 |
This project is a simulation environment for emergency ambulance routing.
|
|
|
|
| 104 |
- `POST /step`
|
| 105 |
- `GET /state`
|
| 106 |
|
| 107 |
+
## Action Space
|
| 108 |
+
|
| 109 |
+
The agent sends one action per step as JSON:
|
| 110 |
+
|
| 111 |
+
```json
|
| 112 |
+
{
|
| 113 |
+
"step": 1,
|
| 114 |
+
"hospital_id": "H3",
|
| 115 |
+
"rationale": "short decision reason"
|
| 116 |
+
}
|
| 117 |
+
```
|
| 118 |
+
|
| 119 |
+
Action fields:
|
| 120 |
+
- `step` (int, >=1): must match current environment step
|
| 121 |
+
- `hospital_id` (str): target hospital identifier
|
| 122 |
+
- `rationale` (str, optional): policy explanation
|
| 123 |
+
|
| 124 |
+
## Observation Space
|
| 125 |
+
|
| 126 |
+
Each `reset()` and `step()` returns an observation with:
|
| 127 |
+
- episode metadata: `episode_id`, `seed`, `task_id`, `scenario_name`, `scenario_difficulty`
|
| 128 |
+
- patient state: `patient_condition`, `required_specialization`, remaining time fields
|
| 129 |
+
- hospital list: `hospital_id`, `distance_km`, `icu`, `specialization`, `traffic`
|
| 130 |
+
- routing history: visited/failed hospitals and failure reasons
|
| 131 |
+
- hidden-state feedback: `last_arrival_outcome` summary (status/reason/suitability)
|
| 132 |
+
- memory snapshot used by the baseline policy
|
| 133 |
+
|
| 134 |
+
Core schema is defined by Pydantic models in:
|
| 135 |
+
- `app/models/action.py`
|
| 136 |
+
- `app/models/observation.py`
|
| 137 |
+
- `app/models/state.py`
|
| 138 |
+
- `app/models/reward.py`
|
| 139 |
+
|
| 140 |
+
## Required Environment Variables
|
| 141 |
+
|
| 142 |
+
Before running `inference.py`, define:
|
| 143 |
+
- `API_BASE_URL`: API base URL for the OpenAI-compatible endpoint
|
| 144 |
+
- `MODEL_NAME`: model name used for rationale generation
|
| 145 |
+
- `HF_TOKEN`: API key/token
|
| 146 |
+
|
| 147 |
+
Windows PowerShell example:
|
| 148 |
+
|
| 149 |
+
```powershell
|
| 150 |
+
$env:API_BASE_URL = "https://api-inference.huggingface.co/v1"
|
| 151 |
+
$env:MODEL_NAME = "your-model-id"
|
| 152 |
+
$env:HF_TOKEN = "your-token"
|
| 153 |
+
```
|
| 154 |
+
|
| 155 |
## Installation
|
| 156 |
|
| 157 |
## 1) Prerequisites
|
app/environment/core.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
|
| 2 |
from pathlib import Path
|
| 3 |
from typing import Any, Literal, cast
|
| 4 |
|
|
@@ -681,7 +681,7 @@ class EmergencyEnv:
|
|
| 681 |
status="rejected",
|
| 682 |
reason="Hidden mismatch at arrival (wrong risky guess). Rerouting required.",
|
| 683 |
validation_details=arrival_outcome.validation_details,
|
| 684 |
-
reward_modifier=0.
|
| 685 |
)
|
| 686 |
return (
|
| 687 |
forced_reject,
|
|
@@ -759,7 +759,7 @@ class EmergencyEnv:
|
|
| 759 |
status="rejected",
|
| 760 |
reason=reason,
|
| 761 |
validation_details=new_validation,
|
| 762 |
-
reward_modifier=0.
|
| 763 |
),
|
| 764 |
0.12,
|
| 765 |
f"Hidden case: {reason}. Rerouting required.",
|
|
@@ -810,7 +810,7 @@ class EmergencyEnv:
|
|
| 810 |
status="rejected",
|
| 811 |
reason="Condition became irreversible after delays",
|
| 812 |
validation_details=arrival_outcome.validation_details,
|
| 813 |
-
reward_modifier=0.
|
| 814 |
),
|
| 815 |
"Partial chain cap: condition became irreversible.",
|
| 816 |
)
|
|
@@ -888,7 +888,7 @@ class EmergencyEnv:
|
|
| 888 |
status="rejected",
|
| 889 |
reason="Condition relapsed after temporary stabilization",
|
| 890 |
validation_details=arrival_outcome.validation_details,
|
| 891 |
-
reward_modifier=0.
|
| 892 |
terminal=False,
|
| 893 |
),
|
| 894 |
"Recovery guard: partial relapsed to rejected.",
|
|
@@ -967,7 +967,7 @@ class EmergencyEnv:
|
|
| 967 |
"dynamic_delay": dynamic_delay,
|
| 968 |
"critical_limit": self.state_data.critical_time_limit_minutes,
|
| 969 |
"specialization_match": self._specialization_match(selected),
|
| 970 |
-
"suitability_score": arrival_outcome.validation_details.patient_suitability if arrival_outcome.validation_details else 0.5,
|
| 971 |
}
|
| 972 |
)
|
| 973 |
|
|
|
|
| 1 |
+
import json
|
| 2 |
from pathlib import Path
|
| 3 |
from typing import Any, Literal, cast
|
| 4 |
|
|
|
|
| 681 |
status="rejected",
|
| 682 |
reason="Hidden mismatch at arrival (wrong risky guess). Rerouting required.",
|
| 683 |
validation_details=arrival_outcome.validation_details,
|
| 684 |
+
reward_modifier=0.001,
|
| 685 |
)
|
| 686 |
return (
|
| 687 |
forced_reject,
|
|
|
|
| 759 |
status="rejected",
|
| 760 |
reason=reason,
|
| 761 |
validation_details=new_validation,
|
| 762 |
+
reward_modifier=0.001,
|
| 763 |
),
|
| 764 |
0.12,
|
| 765 |
f"Hidden case: {reason}. Rerouting required.",
|
|
|
|
| 810 |
status="rejected",
|
| 811 |
reason="Condition became irreversible after delays",
|
| 812 |
validation_details=arrival_outcome.validation_details,
|
| 813 |
+
reward_modifier=0.001,
|
| 814 |
),
|
| 815 |
"Partial chain cap: condition became irreversible.",
|
| 816 |
)
|
|
|
|
| 888 |
status="rejected",
|
| 889 |
reason="Condition relapsed after temporary stabilization",
|
| 890 |
validation_details=arrival_outcome.validation_details,
|
| 891 |
+
reward_modifier=0.001,
|
| 892 |
terminal=False,
|
| 893 |
),
|
| 894 |
"Recovery guard: partial relapsed to rejected.",
|
|
|
|
| 967 |
"dynamic_delay": dynamic_delay,
|
| 968 |
"critical_limit": self.state_data.critical_time_limit_minutes,
|
| 969 |
"specialization_match": self._specialization_match(selected),
|
| 970 |
+
"suitability_score": max(MIN_REWARD, min(MAX_REWARD, arrival_outcome.validation_details.patient_suitability if arrival_outcome.validation_details else 0.5)),
|
| 971 |
}
|
| 972 |
)
|
| 973 |
|
app/environment/validation.py
CHANGED
|
@@ -192,9 +192,10 @@ class HospitalValidator:
|
|
| 192 |
# Add difficulty-based noise
|
| 193 |
if difficulty == "hard":
|
| 194 |
noise = self.rng.uniform(-0.15, 0.15)
|
| 195 |
-
suitability =
|
| 196 |
|
| 197 |
-
|
|
|
|
| 198 |
|
| 199 |
def _determine_outcome(
|
| 200 |
self,
|
|
@@ -271,7 +272,7 @@ class HospitalValidator:
|
|
| 271 |
return (
|
| 272 |
"rejected",
|
| 273 |
f"Hospital cannot admit: {', '.join(rejection_reasons[:2])}",
|
| 274 |
-
0.
|
| 275 |
False,
|
| 276 |
)
|
| 277 |
|
|
@@ -347,7 +348,7 @@ class HospitalValidator:
|
|
| 347 |
return (
|
| 348 |
"rejected",
|
| 349 |
"Condition became non-transferable during delay; immediate critical care failed",
|
| 350 |
-
0.
|
| 351 |
True,
|
| 352 |
)
|
| 353 |
|
|
@@ -359,7 +360,7 @@ class HospitalValidator:
|
|
| 359 |
)
|
| 360 |
|
| 361 |
# Full acceptance
|
| 362 |
-
confidence_bonus =
|
| 363 |
if validation.patient_suitability >= 0.8:
|
| 364 |
confidence_bonus = 1.1
|
| 365 |
elif validation.patient_suitability >= 0.7:
|
|
@@ -378,7 +379,7 @@ class HospitalValidator:
|
|
| 378 |
return (
|
| 379 |
"rejected",
|
| 380 |
"Unexpected complication at arrival",
|
| 381 |
-
0.
|
| 382 |
False,
|
| 383 |
)
|
| 384 |
|
|
@@ -386,7 +387,7 @@ class HospitalValidator:
|
|
| 386 |
return (
|
| 387 |
"accepted",
|
| 388 |
"successful admission under uncertainty",
|
| 389 |
-
|
| 390 |
False,
|
| 391 |
)
|
| 392 |
|
|
|
|
| 192 |
# Add difficulty-based noise
|
| 193 |
if difficulty == "hard":
|
| 194 |
noise = self.rng.uniform(-0.15, 0.15)
|
| 195 |
+
suitability = suitability + noise
|
| 196 |
|
| 197 |
+
# Clamp to strict (0, 1) — validator rejects exact 0.0 and 1.0
|
| 198 |
+
return max(0.001, min(0.999, suitability))
|
| 199 |
|
| 200 |
def _determine_outcome(
|
| 201 |
self,
|
|
|
|
| 272 |
return (
|
| 273 |
"rejected",
|
| 274 |
f"Hospital cannot admit: {', '.join(rejection_reasons[:2])}",
|
| 275 |
+
0.001,
|
| 276 |
False,
|
| 277 |
)
|
| 278 |
|
|
|
|
| 348 |
return (
|
| 349 |
"rejected",
|
| 350 |
"Condition became non-transferable during delay; immediate critical care failed",
|
| 351 |
+
0.001,
|
| 352 |
True,
|
| 353 |
)
|
| 354 |
|
|
|
|
| 360 |
)
|
| 361 |
|
| 362 |
# Full acceptance
|
| 363 |
+
confidence_bonus = 0.999
|
| 364 |
if validation.patient_suitability >= 0.8:
|
| 365 |
confidence_bonus = 1.1
|
| 366 |
elif validation.patient_suitability >= 0.7:
|
|
|
|
| 379 |
return (
|
| 380 |
"rejected",
|
| 381 |
"Unexpected complication at arrival",
|
| 382 |
+
0.001,
|
| 383 |
False,
|
| 384 |
)
|
| 385 |
|
|
|
|
| 387 |
return (
|
| 388 |
"accepted",
|
| 389 |
"successful admission under uncertainty",
|
| 390 |
+
0.999,
|
| 391 |
False,
|
| 392 |
)
|
| 393 |
|