Nothing12Man commited on
Commit
7e0ae0e
Β·
1 Parent(s): 27158b3

docs: add frontmatter and configuration section to README

Browse files
Files changed (1) hide show
  1. README.md +148 -0
README.md CHANGED
@@ -93,6 +93,154 @@ Defined in `models.py` (`VALID_ACTION_TYPES`) and mirrored in `openenv.yaml`:
93
  - `available_specialists: list[str]`
94
  - `previous_actions: list[str]` (canonical `"<action_type>:<target>"`)
95
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
  ---
97
 
98
  ## Reward shaping (non-binary, trajectory-based)
 
93
  - `available_specialists: list[str]`
94
  - `previous_actions: list[str]` (canonical `"<action_type>:<target>"`)
95
 
96
+ ---
97
+ title: "MediRoute OpenEnv"
98
+ emoji: "πŸ₯"
99
+ colorFrom: "blue"
100
+ colorTo: "purple"
101
+ sdk: python
102
+ sdk_version: "1.0"
103
+ python_version: "3.11"
104
+ app_file: app.py
105
+ pinned: false
106
+ ---
107
+
108
+ # MediRoute OpenEnv
109
+
110
+ **MediRoute OpenEnv** is a deterministic **healthcare triage + hospital routing** simulation environment designed for evaluating agent decision-making under realistic clinical constraints.
111
+
112
+ It models the end-to-end flow a real triage system must handle:
113
+ - interpret symptoms + vitals/labs
114
+ - assign severity (non-emergency β†’ critical)
115
+ - route to the right specialist
116
+ - pick an appropriate nearby facility
117
+ - decide between **appointment vs ambulance escalation**
118
+
119
+ This environment is intentionally small, fully deterministic, and strongly typed so it can be used in hackathon evaluation pipelines and reproduced exactly.
120
+
121
+ ---
122
+
123
+ ## Configuration
124
+
125
+ This project exposes several environment variables used at runtime. Keep sensitive keys server-side and out of client-side code (e.g., do not expose `GEOCODER_API_KEY` or `OPENAI_API_KEY` to the browser).
126
+
127
+ Important environment variables:
128
+
129
+ - `OPENAI_API_KEY` β€” (optional) API key for OpenAI if you use the LLM baseline or OpenAI-backed inference.
130
+ - `HF_TOKEN` β€” (optional) Hugging Face token for gated HF models.
131
+ - `API_BASE_URL` β€” (optional) override for OpenAI-compatible endpoints.
132
+ - `MODEL_NAME` β€” (optional) model name to use for LLM inference (default: `gpt-4o-mini` in examples).
133
+ - `USE_LOCAL_EMBEDDINGS` β€” (optional) set to `1`/`true` to enable sentence-transformers fallback for `analyze` when a cloud key is not present.
134
+ - `EMBEDDING_MODEL` β€” (optional) sentence-transformers model id (e.g., `all-MiniLM-L6-v2`) used by local embeddings fallback.
135
+ - `GEOCODER_PROVIDER` β€” (optional) `nominatim` (default) or `mapbox` or `google` if implemented; the server will use this to select reverse geocoding provider.
136
+ - `GEOCODER_API_KEY` β€” (required if using a paid provider) API key for the chosen geocoding provider; keep this server-side and set it as an environment variable or secret.
137
+ - `NEXT_PUBLIC_API_BASE` β€” (frontend) base URL for the backend API; this can point to `http://localhost:8000` in development. Avoid putting secret keys in `NEXT_PUBLIC_` vars.
138
+
139
+ Example `.env` (for local development) β€” do NOT commit this file into git:
140
+
141
+ ```env
142
+ # .env.local (example)
143
+ OPENAI_API_KEY=""
144
+ HF_TOKEN=""
145
+ USE_LOCAL_EMBEDDINGS=1
146
+ EMBEDDING_MODEL="all-MiniLM-L6-v2"
147
+ GEOCODER_PROVIDER=nominatim
148
+ # GEOCODER_API_KEY="your_mapbox_or_google_key"
149
+ NEXT_PUBLIC_API_BASE="http://localhost:8000"
150
+ ```
151
+
152
+ Docker example (passing keys at runtime):
153
+
154
+ ```bash
155
+ docker run --rm -e GEOCODER_PROVIDER=mapbox -e GEOCODER_API_KEY="$MAPBOX_KEY" -e OPENAI_API_KEY="$OPENAI_KEY" -p 8000:8000 mediroute-openenv:latest
156
+ ```
157
+
158
+ Notes:
159
+ - Nominatim (OpenStreetMap) is supported by default for reverse geocoding but has usage limits and a usage policy β€” for production use consider Mapbox or Google and set `GEOCODER_API_KEY` accordingly.
160
+ - Keep API keys on the server. The frontend should call your server endpoints (e.g., `/reverse-geocode`) rather than calling external providers directly.
161
+
162
+ ---
163
+
164
+ ## Why this matters (motivation + utility)
165
+
166
+ Healthcare triage is a high-stakes planning problem with:
167
+ - **multi-step reasoning** (severity β†’ specialist β†’ facility β†’ action)
168
+ - **safety-critical escalation** (ambulance dispatch vs harmful delays)
169
+ - **real-world constraints** (limited specialists, nearby hospitals, and incomplete info)
170
+
171
+ MediRoute is useful for agent evaluation because it tests:
172
+ - **trajectory quality** (progressive reward shaping across steps)
173
+ - **loop avoidance** (duplicate actions and stalling are penalized)
174
+ - **robustness** (invalid actions are handled safely and deterministically)
175
+ - **policy compliance** (terminal actions and episode boundaries are enforced)
176
+
177
+ ---
178
+
179
+ ## Environment overview
180
+
181
+ - **Environment class**: `MediRouteEnv` in `environment.py`
182
+ - **Spec**: `openenv.yaml`
183
+ - **Typed interface**: `models.py` (Pydantic `Observation`, `Action`, `StepResult`)
184
+ - **Tasks**: `tasks.py` (`easy`, `medium`, `hard`)
185
+ - **Deterministic graders**: `graders.py` (`grade_step`, `grade_episode`)
186
+
187
+ OpenEnv interface methods:
188
+ - `reset(difficulty: str) -> Observation`
189
+ - `step(action: Action) -> StepResult` where `StepResult` contains:
190
+ - `observation` (updated `Observation`)
191
+ - `reward` (incremental step reward)
192
+ - `done` (episode termination flag)
193
+ - `info` (diagnostics incl. totals and termination reason)
194
+ - `state() -> Observation` (read-only snapshot)
195
+
196
+ ---
197
+
198
+ ## Tasks (real-world healthcare cases)
199
+
200
+ The tasks represent increasing clinical risk and decision complexity.
201
+
202
+ ### Easy β€” mild illness (primary care)
203
+ - **Scenario**: fever + sore throat with positive strep test
204
+ - **Goal**: classify **low** severity, route to **General Physician**, choose an appropriate clinic, then close with appointment/guidance
205
+ - **Clinical realism**: routine outpatient triage with lab confirmation
206
+
207
+ ### Medium β€” suspected acute coronary syndrome
208
+ - **Scenario**: crushing chest pain, hypertension, ECG ST-elevation, elevated troponin
209
+ - **Goal**: classify **high** severity, route to **Cardiologist**, select a cardiac-capable hospital, then close appropriately
210
+ - **Clinical realism**: time-sensitive cardiology routing
211
+
212
+ ### Hard β€” critical collapse (life-threatening)
213
+ - **Scenario**: unresponsive patient with cyanosis and SpOβ‚‚ crash
214
+ - **Goal**: classify **critical** severity and **dispatch ambulance** (terminal action), avoiding unsafe appointment flows
215
+ - **Clinical realism**: emergency escalation with irreversible harm from delay
216
+
217
+ ---
218
+
219
+ ## Action space
220
+
221
+ Defined in `models.py` (`VALID_ACTION_TYPES`) and mirrored in `openenv.yaml`:
222
+
223
+ - `analyze_symptoms` β€” classify severity (target: `low|moderate|high|critical`)
224
+ - `request_more_info` β€” ask for missing details (target optional)
225
+ - `recommend_specialist` β€” choose specialist (target: a specialist name)
226
+ - `select_hospital` β€” choose facility (target: a hospital name)
227
+ - `book_appointment` β€” close non-emergencies (target optional)
228
+ - `call_ambulance` β€” escalate emergencies (target optional)
229
+ - `provide_temp_guidance` β€” short-term guidance (target optional)
230
+
231
+ ---
232
+
233
+ ## Observation space
234
+
235
+ `Observation` fields (see `models.py` and `openenv.yaml`):
236
+ - `symptoms: str`
237
+ - `lab_report_summary: dict`
238
+ - `severity_score: float` in `[0.0, 1.0]` (updated when severity is analyzed)
239
+ - `location: str`
240
+ - `nearby_hospitals: list[str]`
241
+ - `available_specialists: list[str]`
242
+ - `previous_actions: list[str]` (canonical `"<action_type>:<target>"`)
243
+
244
  ---
245
 
246
  ## Reward shaping (non-binary, trajectory-based)