File size: 12,868 Bytes
1fabaeb | 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 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 | ---
title: ReliefLens AI
emoji: 🚨
colorFrom: red
colorTo: blue
sdk: docker
app_port: 7860
pinned: false
---
# ReliefLens AI
ReliefLens AI is a multimodal, human-in-the-loop emergency triage demo built for the AMD Developer Hackathon. It accepts public field evidence such as text, image uploads, optional audio, browser location, map-selected location, and textual place references, then produces prioritized incidents with recommended resources, location confidence, and operational explanations.
## Public demo
- Hugging Face Space frontend: `https://lablab-ai-amd-developer-hackathon-relieflens-frontend.hf.space`
- AMD FastAPI backend: `http://129.212.185.232:8080`
## Application routes
- Public portal: `/emergencies`
- Private admin: `/admin`
- Admin login: `/admin/login`
- Admin incident queue: `/admin/incidents`
- Admin incident detail: `/admin/incidents/[id]`
- Admin telemetry: `/admin/telemetry`
The public portal is limited to evidence submission and public-safe confirmation details. Sensitive incident management stays behind authenticated admin routes.
## What the system does
- Ingests image, text, optional audio, and location hints
- Resolves location from the best available source without inventing exact coordinates
- Produces prioritized incidents with severity, findings, and recommended resources
- Separates public intake from private incident management
- Shows admin telemetry for backend health and AMD demo metrics
## Location resolution
ReliefLens does not pretend that a photo alone can reveal exact location. Location is resolved in this order:
1. Browser geolocation, if the user shares it
2. Manual map click, if the user selects or corrects a point
3. Image GPS EXIF, if present
4. Textual location hints such as `Santa Ana`
5. `Location requires human review` when evidence is insufficient
If there is no browser location, no map point, no EXIF GPS, and no usable text location, the incident stays unresolved and requires human review.
## Evidence intake behavior
The public `/emergencies` portal supports:
- image upload
- optional audio recording or upload
- `What is happening?`
- `Where is this happening?`
- `Use my current location`
- map click to adjust or set location
- `Analyze Evidence`
Current behavior uses deterministic, rule-based fallback analysis:
- text, filenames, and location hints drive incident classification
- audio files are accepted but returned as `received_not_transcribed` when no ASR model is connected
- images are inspected only for metadata and optional EXIF GPS
- the system does not claim real vision inference unless a model is explicitly connected later
## Qwen-powered incident analysis
Rescue Evidence Intelligence can analyze submitted evidence with a Qwen model through an OpenAI-compatible API.
Required backend variables:
- `QWEN_BASE_URL`
- `QWEN_API_KEY`
- `QWEN_MODEL`
- `QWEN_ENABLED`
Behavior:
- if `QWEN_ENABLED=false`, the backend uses the existing rule-based fallback classifier
- if `QWEN_ENABLED=true`, the backend attempts Qwen analysis first
- if the model server times out, returns malformed JSON, or is unavailable, the backend falls back to `rule_based_fallback`
- the frontend never receives the API key
The admin dashboard shows:
- incident type
- severity
- confidence
- detected risks
- evidence summary
- recommended resources
- requires human review
- analysis provider: `qwen` or `rule_based_fallback`
## Admin incident management
Authenticated admins can:
- sign in through `/admin/login`
- review the full incident queue
- inspect detailed evidence metadata
- update incident status, review state, notes, and assigned team
- inspect backend and AMD telemetry
Required backend environment variables:
- `ADMIN_USERNAME`
- `ADMIN_PASSWORD`
- `ADMIN_TOKEN_SECRET`
- `ADMIN_TOKEN_EXPIRE_MINUTES`
These values must stay on the backend. Do not expose them through `NEXT_PUBLIC_*` variables or commit secrets to git.
## Safety
- Synthetic demo data only
- Human-in-the-loop required
- Not connected to emergency services
- Not for real-world dispatch
- AI suggestions are advisory only
## Security limitations
- The hackathon MVP uses bearer token authentication for `/api/admin/*`
- The frontend stores the admin access token in `sessionStorage`
- This is acceptable for the demo, but production should use HTTPS end-to-end and secure HttpOnly cookies
- Admin credentials must be configured from backend environment variables, not frontend code
## Architecture
Local development:
`Next.js frontend -> /backend rewrite proxy -> FastAPI backend`
Hugging Face Space deployment:
`Hugging Face Docker Space -> nginx on :7860 -> Next.js frontend -> AMD FastAPI backend -> AMD Qwen OpenAI-compatible endpoint`
The browser does not call `localhost:8080`, `127.0.0.1:8080`, the AMD FastAPI public IP, or the AMD Qwen endpoint directly from client-side code. Local frontend requests use `/backend`. The Hugging Face Space build uses same-origin `/api`, which nginx proxies to the AMD FastAPI backend at runtime.
## Backend endpoints
- `GET /health`
- `GET /api/demo/incidents`
- `GET /api/demo/scenario`
- `POST /api/demo/run`
- `POST /api/evidence/intake`
- `GET /api/evidence/status/{tracking_code}`
- `POST /api/demo/analyze-image`
- `POST /api/admin/login`
- `GET /api/admin/me`
- `GET /api/admin/incidents`
- `GET /api/admin/incidents/{incident_id}`
- `PATCH /api/admin/incidents/{incident_id}`
- `GET /api/admin/telemetry`
- `GET /api/amd/performance`
## Local development
### Backend
```bash
cd backend
set ADMIN_USERNAME=admin
set ADMIN_PASSWORD=admin123
set ADMIN_TOKEN_SECRET=local-dev-secret-change-me
set ADMIN_TOKEN_EXPIRE_MINUTES=720
set QWEN_ENABLED=false
python -m pytest tests -v
python -m uvicorn main:app --host 0.0.0.0 --port 8080 --reload
```
Run locally with Qwen disabled:
- keep `QWEN_ENABLED=false`
- the backend will use the rule-based fallback pipeline
Run locally with Qwen through vLLM or another OpenAI-compatible server:
```bash
cd backend
set QWEN_BASE_URL=http://127.0.0.1:8000/v1
set QWEN_API_KEY=token-abc123
set QWEN_MODEL=Qwen/Qwen2.5-7B-Instruct
set QWEN_ENABLED=true
python -m uvicorn main:app --host 0.0.0.0 --port 8080 --reload
```
### Frontend
```bash
cd frontend
npm install
npm run build
npm run dev
```
Local frontend environment file:
```env
NEXT_PUBLIC_API_URL=/backend
NEXT_PUBLIC_API_BASE_URL=/backend
NEXT_PUBLIC_BACKEND_URL=/backend
BACKEND_ORIGIN=http://localhost:8080
```
Local proxy checks:
- `http://localhost:3000/backend/health`
- `http://localhost:3000/admin/login`
Local admin login test credentials:
- username: `admin`
- password: `admin123`
## Deployment to AMD Cloud
Recommended topology:
- AMD VM: FastAPI backend on `:8080`
- AMD VM: external Qwen OpenAI-compatible endpoint on `:8000`
- Hugging Face Space: public container on `:7860`
On the AMD VM:
```bash
git clone https://github.com/<your-org-or-user>/ReliefLensAI.git
cd ReliefLensAI
bash scripts/deploy_backend_amd.sh
cp backend/.env.example backend/.env
```
Edit `backend/.env` for your VM. Minimum values:
```env
APP_ENV=production
DEBUG=false
DEMO_MODE=false
STORAGE_PATH=./data
CORS_ORIGINS=https://YOUR_SPACE.hf.space
QWEN_ENABLED=true
QWEN_BASE_URL=http://127.0.0.1:8000/v1
QWEN_API_KEY=amd-qwen-demo-key
QWEN_MODEL=Qwen/Qwen2-7B-Instruct
ADMIN_USERNAME=admin
ADMIN_PASSWORD=admin123
ADMIN_TOKEN_SECRET=relieflens-demo-secret-change-this
ADMIN_TOKEN_EXPIRE_MINUTES=720
```
Then start the backend:
```bash
bash scripts/start_backend_amd.sh
curl http://127.0.0.1:8080/health
curl http://129.212.185.232:8080/health
```
If Qwen is running separately on the same VM, verify it first:
```bash
curl http://127.0.0.1:8000/v1/models -H "Authorization: Bearer amd-qwen-demo-key"
```
## Deployment to Hugging Face Docker Space
The repository now includes a root `Dockerfile` for a single Hugging Face Docker Space container.
Container behavior:
- Next.js frontend runs internally on `127.0.0.1:3000`
- `nginx` exposes only port `7860`
- `/` routes to the Next.js frontend
- `/api/*` routes to the AMD FastAPI backend via `BACKEND_ORIGIN`
- `/health` routes to `${BACKEND_ORIGIN}/health`
Public browser behavior:
- the browser calls same-origin `/api` in the Hugging Face Space build
- no Qwen secret is exposed to the frontend bundle
- the Space does not call Qwen directly
- Qwen credentials stay only on the AMD backend environment
Space variables:
- `NEXT_PUBLIC_API_URL=/api`
- `NEXT_PUBLIC_API_BASE_URL=/api`
- `NEXT_PUBLIC_BACKEND_URL=/api`
- `BACKEND_ORIGIN=http://129.212.185.232:8080`
Do not put `QWEN_API_KEY`, admin credentials, or token secrets in any `NEXT_PUBLIC_*` variable or Hugging Face frontend variable.
Build and push flow:
1. Push this repository to the Hugging Face Space repo.
2. Configure the Space variables above.
3. Wait for the Docker build to finish.
4. Test:
- `https://YOUR_SPACE.hf.space/health`
- `https://YOUR_SPACE.hf.space/api/demo/incidents`
- `https://YOUR_SPACE.hf.space/emergencies`
The Space container uses the root `Dockerfile` and serves the full app on port `7860`.
Deployment flow:
1. Create a Docker Space on Hugging Face.
2. Push this repository root to the Space repository.
3. Configure these Variables:
- `NEXT_PUBLIC_API_URL=/api`
- `NEXT_PUBLIC_API_BASE_URL=/api`
- `NEXT_PUBLIC_BACKEND_URL=/api`
- `BACKEND_ORIGIN=http://129.212.185.232:8080`
4. Wait for the Docker build.
5. Validate:
- `https://YOUR_SPACE.hf.space/health`
- `https://YOUR_SPACE.hf.space/api/demo/incidents`
- `https://YOUR_SPACE.hf.space/admin/login`
## Hugging Face Space + AMD Qwen Deployment
This deployment mode keeps both Qwen and FastAPI on AMD infrastructure while Hugging Face hosts only the public UI and reverse proxy.
Architecture:
`Hugging Face Docker Space -> nginx on :7860 -> Next.js on :3000 -> AMD FastAPI on :8080 -> AMD Qwen OpenAI-compatible endpoint`
Required AMD backend runtime variables:
- `QWEN_ENABLED=true`
- `QWEN_BASE_URL=http://127.0.0.1:8000/v1`
- `QWEN_MODEL=Qwen/Qwen2-7B-Instruct`
- `QWEN_API_KEY=amd-qwen-demo-key`
Required Hugging Face Space variables:
- `NEXT_PUBLIC_API_URL=/api`
- `NEXT_PUBLIC_API_BASE_URL=/api`
- `NEXT_PUBLIC_BACKEND_URL=/api`
- `BACKEND_ORIGIN=http://129.212.185.232:8080`
Optional local Docker smoke test before pushing to Hugging Face:
```bash
docker build -t relieflens-space .
docker run --rm -p 7860:7860 \
-e NEXT_PUBLIC_API_URL=/api \
-e NEXT_PUBLIC_API_BASE_URL=/api \
-e NEXT_PUBLIC_BACKEND_URL=/api \
-e BACKEND_ORIGIN=http://129.212.185.232:8080 \
relieflens-space
```
Then test:
- `http://localhost:7860/health`
- `http://localhost:7860/api/demo/incidents`
- `http://localhost:7860/admin/login`
## Final deployment checklist
1. Verify Qwen on AMD:
- `curl http://127.0.0.1:8000/v1/models -H "Authorization: Bearer amd-qwen-demo-key"`
2. Start AMD backend:
- `bash scripts/start_backend_amd.sh`
3. Verify AMD backend locally:
- `curl http://127.0.0.1:8080/health`
4. Verify AMD backend publicly:
- `curl http://129.212.185.232:8080/health`
5. Configure Hugging Face Space variables:
- `NEXT_PUBLIC_API_URL=/api`
- `NEXT_PUBLIC_API_BASE_URL=/api`
- `NEXT_PUBLIC_BACKEND_URL=/api`
- `BACKEND_ORIGIN=http://129.212.185.232:8080`
6. Push to a new Docker Space.
7. Test:
- `https://SPACE.hf.space/health`
- `https://SPACE.hf.space/api/demo/incidents`
- `https://SPACE.hf.space/emergencies`
8. Submit the seeded flood report and verify the admin dashboard shows `analysis_provider=qwen`.
## Known limitations
- Qwen analysis depends on a reachable OpenAI-compatible model server returning valid JSON
- If Qwen is disabled or fails, the system falls back to rule-based analysis
- Audio is accepted but not transcribed unless an ASR model is connected later
- EXIF GPS is only available for images that actually contain GPS metadata
- Text-location resolution is intentionally conservative and does not invent precise coordinates
- Map clicks are user-provided hints, not verified GPS
- Human review remains mandatory for operational use
## Flood demo case
To test the seeded flood case in the admin dashboard or API, use evidence like:
- Evidence text:
`A severe flash flood is affecting a residential area. Streets are partially flooded, several vehicles are stuck, and people may be trapped inside nearby buildings. Water level appears to be rising quickly after heavy rainfall.`
- Image findings:
`Flooded urban street, muddy water reaching residential entrances, stuck cars, people moving to higher ground.`
- Audio transcript:
`No audio uploaded.`
- Location:
browser geolocation with `confidence=0.90`
Expected result:
- `incident_type=flood`
- `severity=critical`
- `priority=P0`
- `requires_human_review=true`
- provider `qwen` when available, otherwise `rule_based_fallback`
|