# Project export: AlphaRescue

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: UC Berkeley AI Hackathon 2025
- Tagline: First to know, First to act!
- Devpost: https://devpost.com/software/alpharescue
- GitHub: https://github.com/Preetam3620/Alpha-Rescue
- Result: winner (Fetch AI: Best Use of Fetch AI)
- Team: 4 GitHub contributor(s) — Preetam Maske (1 commits), Shantanu (1 commits), Parth Mhakavekar (1 commits), Purva Uday Bansod (1 commits)

## Devpost submission (written by the team)

### Inspiration

In moments of emergency, every second counts. We were inspired by the idea that AI should be the first to know and the fastest to act. From natural disasters to critical medical needs, we envisioned a system that could assist first responders with intelligent decision-making. Thus, AlphaRescue was born — a smart, responsive, and location-aware emergency dispatch assistant.

### What it does

AlphaRescue is a fully autonomous, AI-powered first responder system that listens to live distress calls, understands the situation, and intelligently coordinates with emergency authorities to dispatch help. A distressed user initiates a call through VAPI, our voice-based AI assistant trained specifically to handle emergency situations and provide immediate, scenario-based guidance. The voice transcripts from VAPI are summarized in real time using Gemini, converting lengthy, unstructured conversations into concise, actionable incident briefs while also detecting potential false alarms. A network of specialized Fetch.ai uAgents then takes over, interacting with each other to evaluate the situation, assess real-time authority availability, and formulate a coordinated plan of action. Each agent is designed to reason, communicate, and make independent decisions — working together to ensure the most effective response is triggered. The agents use a Retrieval-Augmented Generation (RAG) pipeline with Gemini to identify and rank the nearest, most appropriate hospital based on the emergency type and geographic location. Supabase serves as our real-time backend, storing both vector embeddings and structured facility data to support fast, intelligent retrieval. Our specialized agents also use Groq’s ultra-fast LLM to classify the ambulance type required — BLS, ALS, or CCT — ensuring the right unit is dispatched to the scene. These fully autonomous AI agents, built using uAgents, manage the entire downstream flow: summarizing transcripts, selecting facilities, and using VAPI to notify the appropriate authorities — all in a seamless, hands-free manner. A live dashboard, built using Vercel's v0.dev and Mapbox, provides real-time visualization of incidents, responders, and dispatch outcomes. AlphaRescue transforms emergency calls into immediate, intelligent action — combining voice, geospatial reasoning, and autonomous agents to reduce response time and save lives faster.

### How we built it

Agent-based architecture built with Fetch.ai uAgents leveraging AgentVerse platform to simulate communication between emergency dispatch agents. AI-powered classification using Groq's LLM to determine the type of ambulance needed (BLS, ALS, or CCT). AI based summaryLeveraged Gemini to summarize verbose VAPI voice call transcripts in real-time. These concise summaries were then fed directly to the uAgents to enhance decision making and reduce cognitive load on the system. Geolocation-based facility selection using geopy and Supabase, built a RAG to find the closest, most suitable facility. Supabase as a real-time backend for storing facility data. Asynchronous system using Python, pydantic, and modern microservice principles.

### Challenges we ran into

Syncing communication between multiple agents in a multi-process async environment. Managing agent registration and compatibility with the Almanac contract. Identifying false spam calls with the help of Gemini and reacting based on it, ensuring genuine calls does not go unattended. Handling LLM classification edge cases and ensuring consistent ambulance type decisions. Real-time Supabase query performance and ENUM filtering.

### Accomplishments we're proud of

Designed a seamless end-to-end emergency dispatch pipeline powered by AI agents and real-time data. Enabled real-time summarization of live voice calls using Gemini, dramatically reducing LLM input size and improving response latency. Successfully integrated Groq’s blazing-fast LLM to classify medical emergencies with high accuracy. Achieved fast and accurate ambulance dispatch using geospatial filtering and facility prioritization logic. Built a plug-and-play agent ecosystem that can be extended to police, fire, or disaster response domains. ##

### What we learned

How to orchestrate autonomous agents in a distributed, real-time environment using uAgents. Real-world challenges in LLM usage like hallucination, consistency, and prompt design. Importance of summarization pipelines when dealing with long-form audio transcripts in high-pressure scenarios. How to build scalable geolocation-aware search using PostgREST and Supabase. The power of combining structured backend logic with reasoning-driven LLM decision-making.

### What's next

Integrate a trust and reputation layer to evaluate and ignore prank/spam calls automatically. Add support for multi-modal inputs like images/videos from users to enhance context and classification accuracy. Extend to support fire and police emergencies with role-specific uAgents and classifiers. Deploy a mobile-first frontend for citizens and responders with real-time tracking and notifications. Train an internal model using fine-tuned incident data for higher accuracy and offline deployments.

## README (from the GitHub repository)

# AlphaRescue 🚨

> **"First to know, First to act!"**

An AI-powered emergency dispatch system designed to rapidly respond to distress calls by intelligently coordinating with emergency authorities.

**🏆 Winner: Fetch AI Best Use of Fetch AI - UC Berkeley AI Hackathon 2025**

## 🌟 Overview

AlphaRescue revolutionizes emergency response by combining cutting-edge AI technologies with autonomous agent networks to create a faster, more intelligent dispatch system. Our platform processes emergency calls in real-time, automatically assesses situations, and coordinates with the appropriate emergency services.

## ✨ Key Features

- **🎙️ Voice-based AI Assistant**: Powered by VAPI for natural emergency call handling
- **📝 Real-time Call Transcription**: Automatic summarization using Gemini AI
- **🤖 Autonomous Agent Network**: Intelligent situation assessment and resource allocation
- **🏥 Smart Facility Selection**: Geolocation-based hospital and emergency service matching
- **📊 Real-time Dashboard**: Live incident monitoring and tracking
- **🚑 Intelligent Ambulance Dispatch**: Automated selection of appropriate ambulance types


## 🛠️ Technologies Used

### Frontend
- **React.js** with TypeScript
- **Tailwind CSS** for styling
- **Mapbox GL** for mapping
- **Lucide React** for icons

### Backend
- **Node.js** with Express
- **Python** for AI agents
- **Fetch.ai uAgents** for autonomous agents
- **Supabase** for database and real-time features

### AI & ML
- **Gemini AI** for transcription and summarization
- **Groq LLM** for fast inference
- **OpenAI** for additional AI capabilities

### Infrastructure
- **Vercel** for deployment
- **VAPI** for voice integration

## 🚀 Getting Started

### Prerequisites

- Node.js (v16 or higher)
- Python 3.8+
- Supabase account
- API keys for Gemini, Groq, and VAPI

### Installation

1. **Clone the repository**
   ```bash
   git clone https://github.com/yourusername/Alpha-Rescue.git
   cd Alpha-Rescue
   ```

2. **Setup Frontend Dashboard**
   ```bash
   cd Dashboard/dashboard-frontend
   npm install
   npm start
   ```

3. **Setup Backend Dashboard**
   ```bash
   cd Dashboard/dashboard-backend
   npm install
   npm start
   ```

4. **Setup Python Agents**
   ```bash
   cd fetch-agent-fire-responder
   pip install -r requirements.txt
   python Orchestrator.py
   ```

### Environment Variables

Create `.env` files in the respective directories with:

```env
# Supabase
SUPABASE_URL=your_supabase_url
SUPABASE_KEY=your_supabase_key

# AI Services
GEMINI_API_KEY=your_gemini_key
GROQ_API_KEY=your_groq_key
OPENAI_API_KEY=your_openai_key

# VAPI
VAPI_API_KEY=your_vapi_key

# Mapbox
MAPBOX_ACCESS_TOKEN=your_mapbox_token
```

## 📁 Project Structure

```
Alpha-Rescue/
├── Dashboard/
│   ├── dashboard-frontend/     # React frontend application
│   │   ├── src/
│   │   │   ├── components/     # React components
│   │   │   └── types.ts        # TypeScript definitions
│   │   └── package.json
│   └── dashboard-backend/      # Express.js backend
│       ├── server.js           # Main server file
│       └── package.json
└── fetch-agent-fire-responder/ # Python agents
    ├── Orchestrator.py         # Main orchestrator agent
    ├── paramedic/              # Paramedic agents
    │   ├── ambulance_agent.py  # Ambulance dispatch logic
    │   └── groq_classifier.py  # AI classification
    ├── hospital_agent.py       # Hospital matching agent
    ├── firestation_lookup_agent.py # Fire station agent
    ├── police_integration.py   # Police coordination
    └── requirements.txt        # Python dependencies
```

## 🎯 How It Works

1. **Emergency Call Received**: VAPI processes incoming voice calls
2. **Real-time Transcription**: Gemini AI transcribes and summarizes the call
3. **Agent Network Activation**: Fetch.ai agents assess the situation
4. **Resource Allocation**: System identifies optimal emergency services
5. **Dispatch Coordination**: Automated coordination with hospitals, fire stations, or police
6. **Real-time Monitoring**: Dashboard provides live updates on incident status

## 🏆 Achievements

- **UC Berkeley AI Hackathon 2025 Winner**: Fetch AI Best Use of Fetch AI
- Successfully demonstrated end-to-end emergency response automation
- Integrated multiple AI technologies into a cohesive system
- Built scalable microservice architecture

## 🚧 Challenges Overcome

- **Multi-agent Communication**: Synchronized communication between distributed agents
- **Agent Registration Management**: Efficient handling of agent lifecycle
- **Spam Call Detection**: AI-powered filtering of non-emergency calls
- **LLM Edge Cases**: Robust handling of AI classification uncertainties

## 🔮 What's Next

- **Trust & Reputation Layer**: Add reliability scoring for emergency services
- **Multi-modal Support**: Voice, text, and image-based emergency reporting
- **Extended Coverage**: Support for fire department and police emergencies
- **Mobile-first Frontend**: Dedicated mobile application
- **Custom Model Training**: Train internal models with incident data
- **Real-world Deployment**: Partner with emergency services for pilot programs


## 📄 License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

## 🤝 Contributing

We welcome contributions! Please feel free to submit a Pull Request.

## 📞 Contact

For questions or support, please reach out to the team through our [GitHub repository](https://github.com/yourusername/Alpha-Rescue).

---

**AlphaRescue** - Transforming emergency response through AI innovation. 🚑✨

## Detected evidence (automated analysis)

Indexed codebase: 37 recognized source files, 121 KB.
- CSS (language) — detected in the code
- Express (technology) — detected in the code
- JavaScript (language) — detected in the code
- OpenAI (technology) — detected in the code
- Python (language) — detected in the code
- React (technology) — detected in the code
- Supabase (technology) — detected in the code
- Tailwind CSS (technology) — detected in the code
- TypeScript (language) — detected in the code
- Google Gemini (technology) — claimed on Devpost, not found in the code
- Node.js (technology) — claimed on Devpost, not found in the code
- Vercel (technology) — claimed on Devpost, not found in the code

## Codebase structure (from repository index)

### Files (43 of 43)

```
.gitignore
Dashboard/dashboard-backend/package.json
Dashboard/dashboard-backend/README.md
Dashboard/dashboard-backend/server.js
Dashboard/dashboard-frontend/package.json
Dashboard/dashboard-frontend/README.md
Dashboard/dashboard-frontend/src/App.css
Dashboard/dashboard-frontend/src/App.test.tsx
Dashboard/dashboard-frontend/src/App.tsx
Dashboard/dashboard-frontend/src/components/AgentEvent.tsx
Dashboard/dashboard-frontend/src/components/FireDepartmentInfo.tsx
Dashboard/dashboard-frontend/src/components/HospitalInfo.tsx
Dashboard/dashboard-frontend/src/components/MapboxMap.css
Dashboard/dashboard-frontend/src/components/MapboxMap.tsx
Dashboard/dashboard-frontend/src/components/ParamedicInfo.tsx
Dashboard/dashboard-frontend/src/components/PoliceInfo.tsx
Dashboard/dashboard-frontend/src/components/SearchBox.tsx
Dashboard/dashboard-frontend/src/components/UserInfoCard.css
Dashboard/dashboard-frontend/src/components/UserInfoCard.tsx
Dashboard/dashboard-frontend/src/index.css
Dashboard/dashboard-frontend/src/index.tsx
Dashboard/dashboard-frontend/src/output.css
Dashboard/dashboard-frontend/src/react-app-env.d.ts
Dashboard/dashboard-frontend/src/reportWebVitals.ts
Dashboard/dashboard-frontend/src/setupTests.ts
Dashboard/dashboard-frontend/src/types.ts
Dashboard/dashboard-frontend/tsconfig.json
fetch-agent-fire-responder/address_2_coord.py
fetch-agent-fire-responder/firestation_lookup_agent.py
fetch-agent-fire-responder/hospital_agent.py
fetch-agent-fire-responder/Orchestrator.py
fetch-agent-fire-responder/paramedic/__init__.py
fetch-agent-fire-responder/paramedic/ambulance_agent.py
fetch-agent-fire-responder/paramedic/groq_classifier.py
fetch-agent-fire-responder/paramedic/main.py
fetch-agent-fire-responder/paramedic/messages.py
fetch-agent-fire-responder/paramedic/requirements.txt
fetch-agent-fire-responder/police_integration.py
fetch-agent-fire-responder/rag_classifier.py
fetch-agent-fire-responder/README.md
fetch-agent-fire-responder/requirements.txt
fetch-agent-fire-responder/vapi_notifier_agent.py
README.md
```

### Dependencies

- Dashboard/dashboard-backend/package.json: express@^4.18.2
- Dashboard/dashboard-frontend/package.json: @tailwindcss/cli@^4.1.10, @testing-library/dom@^10.4.0, @testing-library/jest-dom@^6.6.3, @testing-library/react@^16.3.0, @testing-library/user-event@^13.5.0, @types/jest@^27.5.2, @types/node@^16.18.126, @types/react@^19.1.8, @types/react-dom@^19.1.6, autoprefixer@^10.4.21, lucide-react@^0.519.0, mapbox-gl@^3.13.0, postcss@^8.5.6, react@^19.1.0, react-dom@^19.1.0, react-scripts@5.0.1, tailwindcss@^4.1.10, typescript@^4.9.5, web-vitals@^2.1.4
- fetch-agent-fire-responder/paramedic/requirements.txt: geopy@>=2.4.1, groq, httpx@>=0.27.0, openai@>=1.30.1, python-dotenv@>=1.0.0, supabase@>=1.0.3, uagents@>=0.10.0

### Recent commits (newest first)

- docs: add comprehensive README with project overview and setup instructions
- feat: add basic Express server with webhook and SSE endpoints
- feat: add SearchBox component for user queries
- Add ambulance dispatch agent and related components
- Add initial implementation of AI-powered emergency dispatch system

## Key source files (fetched from GitHub, selected and truncated for size)

### fetch-agent-fire-responder/requirements.txt

```
��a i o h a p p y e y e b a l l s = = 2 . 6 . 1  
 a i o h t t p = = 3 . 1 2 . 1 3  
 a i o s i g n a l = = 1 . 3 . 2  
 a n n o t a t e d - t y p e s = = 0 . 7 . 0  
 a n y i o = = 4 . 9 . 0  
 a t t r s = = 2 5 . 3 . 0  
 b e c h 3 2 = = 1 . 2 . 0  
 c a c h e t o o l s = = 5 . 5 . 2  
 c e r t i f i = = 2 0 2 5 . 6 . 1 5  
 c h a r s e t - n o r m a l i z e r = = 3 . 4 . 2  
 c l i c k = = 8 . 2 . 1  
 c o l o r a m a = = 0 . 4 . 6  
 c o s m p y = = 0 . 1 1 . 1  
 d e p r e c a t i o n = = 2 . 1 . 0  
 d i s t l i b = = 0 . 3 . 9  
 d i s t r o = = 1 . 9 . 0  
 e c d s a = = 0 . 1 9 . 1  
 f i l e l o c k = = 3 . 1 8 . 0  
 f r o z e n l i s t = = 1 . 7 . 0  
 g e o g r a p h i c l i b = = 2 . 0  
 g e o p y = = 2 . 4 . 1  
 g o o g l e - a i - g e n e r a t i v e l a n g u a g e = = 0 . 6 . 1 5  
 g o o g l e - a p i - c o r e = = 2 . 2 5 . 1  
 g o o g l e - a p i - p y t h o n - c l i e n t = = 2 . 1 7 3 . 0  
 g o o g l e - a u t h = = 2 . 4 0 . 3  
 g o o g l e - a u t h - h t t p l i b 2 = = 0 . 2 . 0  
 g o o g l e - g e n a i = = 1 . 2 1 . 1  
 g o o g l e - g e n e r a t i v e a i = = 0 . 8 . 5  
 g o o g l e a p i s - c o m m o n - p r o t o s = = 1 . 7 0 . 0  
 g o o g l e m a p s = = 4 . 1 0 . 0  
 g o t r u e = = 2 . 1 2 . 0  
 g r o q = = 0 . 2 8 . 0  
 g r p c i o = = 1 . 7 3 . 0  
 g r p c i o - s t a t u s = = 1 . 7 1 . 0  
 h 1 1 = = 0 . 1 6 . 0  
 h 2 = = 4 . 2 . 0  
 h p a c k = = 4 . 1 . 0  
 h t t p c o r e = = 1 . 0 . 9  
 h t t p l i b 2 = = 0 . 2 2 . 0  
 h t t p x = = 0 . 2 8 . 1  
 h y p e r f r a m e = = 6 . 1 . 0  
 i d n a = = 3 . 1 0  
 i n i c o n f i g = = 2 . 1 . 0  
 j i t e r = = 0 . 1 0 . 0  
 j s o n s c h e m a = = 4 . 2 4 . 0  
 j s o n s c h e m a - s p e c i f i c a t i o n s = = 2 0 2 5 . 4 . 1  
 m u l t i d i c t = = 6 . 5 . 0  
 o p e n a i = = 1 . 9 0 . 0  
 p a c k a g i n g = = 2 5 . 0  
 p l a t f o r m d i r s = = 4 . 3 . 8  
 p l u g g y = = 1 . 6 . 0  
 p o s t g r e s t = = 1 . 0 . 2  
 p r o p c a c h e = = 0 . 3 . 2  
 p r o t o - p l u s = = 1 . 2 6 . 1  
 p r o t o b u f = = 5 . 2 9 . 5  
 p y a s n 1 = = 0 . 6 . 1  
 p y a s n 1 _ m o d u l e s = = 0 . 4 . 2  
 p y c r y p t o d o m e = = 3 . 2 3 . 0  
 p y d a n t i c = = 2 . 1 1 . 7  
 p y d a n t i c _ c o r e = = 2 . 3 3 . 2  
 P y g m e n t s = = 2 . 1 9 . 1  
 P y J W T = = 2 . 1 0 . 1  
 p y p a r s i n g = = 3 . 2 . 3  
 p y t e s t = = 8 . 4 . 1  
 p y t e s t - m o c k = = 3 . 1 4 . 1  
 p y t h o n - d a t e u t i l = = 2 . 9 . 0 . p o s t 0  
 p y t h o n - d o t e n v = = 1 . 1 . 0  
 r e a l t i m e = = 2 . 4 . 3  
 r e f e r e n c i n g = = 0 . 3 6 . 2  
 r e q u e s t s = = 2 . 3 2 . 4  
 r p d s - p y = = 0 . 2 5 . 1  
 r s a = = 4 . 9 . 1  
 s i x = = 1 . 1 7 . 0  
 s n i f f i o = = 1 . 3 . 1  
 s o r t e d c o n t a i n e r s = = 2 . 4 . 0  
 s t o r a g e 3 = = 0 . 1 1 . 3  
 S t r E n u m = = 0 . 4 . 1 5  
 s u p a b a s e = = 2 . 1 5 . 3  
 s u p a f u n c = = 0 . 9 . 4  
 t e n a c i t y = = 8 . 5 . 0  
 t q d m = = 4 . 6 7 . 1  
 t y p i n g - i n s p e c t i o n = = 0 . 4 . 1  
 t y p i n g _ e x t e n s i o n s = = 4 . 1 4 . 0  
 u a g e n t s = = 0 . 2 2 . 5  
 u a g e n t s - c o r e = = 0 . 3 . 3  
 u r i t e m p l a t e = = 4 . 2 . 0  
 u r l l i b 3 = = 2 . 5 . 0  
 u v i c o r n = = 0 . 3 4 . 3  
 v i r t u a l e n v = = 2 0 . 3 1 . 2  
 w e b s o c k e t s = = 1 4 . 2  
 y a r l = = 1 . 2 0 . 1  
 
```

### fetch-agent-fire-responder/paramedic/requirements.txt

```
uagents>=0.10.0
python-dotenv>=1.0.0
geopy>=2.4.1
supabase>=1.0.3
httpx>=0.27.0
openai>=1.30.1
groq
```

### Dashboard/dashboard-backend/package.json

```
{
  "name": "dashboard-backend",
  "version": "1.0.0",
  "main": "server.js",
  "type": "commonjs",
  "scripts": {
    "start": "node server.js"
  },
  "dependencies": {
    "express": "^4.18.2"
  }
}

```

### Dashboard/dashboard-frontend/package.json

```
{
  "name": "real-estate-frontend",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@tailwindcss/cli": "^4.1.10",
    "@testing-library/dom": "^10.4.0",
    "@testing-library/jest-dom": "^6.6.3",
    "@testing-library/react": "^16.3.0",
    "@testing-library/user-event": "^13.5.0",
    "@types/jest": "^27.5.2",
    "@types/node": "^16.18.126",
    "@types/react": "^19.1.8",
    "@types/react-dom": "^19.1.6",
    "lucide-react": "^0.519.0",
    "mapbox-gl": "^3.13.0",
    "react": "^19.1.0",
    "react-dom": "^19.1.0",
    "react-scripts": "5.0.1",
    "typescript": "^4.9.5",
    "web-vitals": "^2.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "autoprefixer": "^10.4.21",
    "postcss": "^8.5.6",
    "tailwindcss": "^4.1.10"
  }
}

```

### fetch-agent-fire-responder/paramedic/main.py

```python
# main.py
import asyncio
from uagents import Agent, Bureau, Context
from messages import AmbulanceRequest
from ambulance_agent import ambulance_agent

# Create a test sender agent
sender = Agent(name="test_sender",
    seed="test_sender_seed",
    port=8010,
    endpoint="http://127.0.0.1:8010/submit",)

@sender.on_event("startup")
async def send_request(ctx: Context):
    request = AmbulanceRequest(
        request_id="test-001",
        note="A person collapsed and is unconscious, possibly a heart issue.",
        lat=37.8715,
        lon=-122.2730
    )
    
    await ctx.send(ambulance_agent.address, request)

# Set up Bureau and run
bureau = Bureau()
bureau.add(sender)
bureau.add(ambulance_agent)

if __name__ == "__main__":
    bureau.run()

```

### Dashboard/dashboard-backend/server.js

```javascript
// Basic Express server with webhook and SSE endpoints
const express = require('express');
const EventEmitter = require('events');

const app = express();
const PORT = process.env.PORT || 3000;

// Event emitter for broadcasting data to SSE clients
const agentEmitter = new EventEmitter();

// Helper to parse webhook payload (customize as needed)
function parse_webhook_payload(envelope) {
  // Example: just return the envelope as-is
  return envelope;
}

// Broadcast data to all SSE clients
function broadcastToClients(data) {
  agentEmitter.emit('data', data);
}

// Webhook endpoint
app.post('/api/webhook', express.json(), (req, res) => {
  const envelope = req.body;
  const data = parse_webhook_payload(envelope);
  broadcastToClients(data);
  res.sendStatus(200);
});

// SSE endpoint
app.get('/events', (req, res) => {
  res.writeHead(200, {
    'Content-Type': 'text/event-stream',
    'Cache-Control': 'no-cache',
    'Access-Control-Allow-Origin': '*',
    Connection: 'keep-alive'
  });
  // Send a comment to keep the connection alive
  res.write(': connected\n\n');

  // Listener for new data
  const onData = d => {
    res.write(`data: ${JSON.stringify(d)}\n\n`);
  };
  agentEmitter.on('data', onData);

  // Clean up on client disconnect
  req.on('close', () => {
    agentEmitter.off('data', onData);
    res.end();
  });
});

app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

```

### Dashboard/dashboard-frontend/src/App.tsx

```typescript
import React from 'react';
import './App.css';
import MapboxMap from './components/MapboxMap';

function App() {
  return (
    <div className="App">
        
      <MapboxMap />
    </div>
  );
}

export default App;

```

### Dashboard/dashboard-frontend/src/index.tsx

```typescript
import React from 'react';
import ReactDOM from 'react-dom/client';
import './output.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

```

### fetch-agent-fire-responder/address_2_coord.py

```python
import requests
import google.generativeai as genai

# Your API keys
GOOGLE_MAPS_API_KEY="AIzaSyCBwkO7BVuyjU_m8LE-j7fMhEWs7d4sjkM"
GEMINI_API_KEY="AIzaSyAMBaufidL79w1X6tf3nnTMjvuvoFYj_1U"

# Configure Gemini
genai.configure(api_key=GEMINI_API_KEY)
model = genai.GenerativeModel("gemini-2.5-flash")

def clean_address_with_gemini(vague_input: str) -> str:
    """
    Use Gemini to convert vague location input into a clean, Google Maps–compatible address.
    """
    prompt = f"""
Given a vague or informal place description, return a cleaned-up, Google Maps-compatible address.
Include street names, city, and state.

Input: "{vague_input}"
Cleaned Address:"""

    response = model.generate_content(prompt)
    return response.text.strip().replace("Cleaned Address:", "").strip('" ').strip()

def get_coordinates_from_google(cleaned_address: str) -> tuple[float, float]:
    """
    Use Google Maps Geocoding API to get precise coordinates of a cleaned address.
    """
    url = "https://maps.googleapis.com/maps/api/geocode/json"
    params = {
        'address': cleaned_address,
        'key': GOOGLE_MAPS_API_KEY
    }
    response = requests.get(url, params=params)
    data = response.json()

    if data['status'] == 'OK' and data['results']:
        location = data['results'][0]['geometry']['location']
        return float(location['lat']), float(location['lng'])
    else:
        raise ValueError(f"❌ Google Maps API Error: {data.get('status')} — {data.get('error_message')}")

def get_smart_coordinates(vague_input: str) -> tuple[float, float]:
    """
    Full flow: vague input → Gemini cleans it → Google Maps returns precise coordinates.
    Returns: latitude (float), longitude (float), cleaned address (str)
    """
    print(f"🧠 Raw Input: {vague_input}")
    cleaned_address = clean_address_with_gemini(vague_input)
    print(f"📍 Gemini Cleaned Address: {cleaned_address}")
    lat, lon = get_coordinates_from_google(cleaned_address)
    return lat, lon

# ✅ Example usage
if __name__ == "__main__":
    vague_place = input("📍 Enter a vague address or place name: ")
    try:
        lat, lon = get_smart_coordinates(vague_place)
        print("✅ Latitude:", lat)
        print("✅ Longitude:", lon)
        print(f"🔗 Google Maps: https://www.google.com/maps?q={lat},{lon}")
    except Exception as e:
        print(str(e))
    
```

### fetch-agent-fire-responder/rag_classifier.py

```python
# rag_classifier.py

import json
import os
import re
import ast
from typing import List, Optional
from dotenv import load_dotenv
from pydantic import BaseModel
from supabase import create_client
from google.generativeai import configure, GenerativeModel
from sentence_transformers import SentenceTransformer

class EmergencyNote(BaseModel):
    note: str
    latitude: float
    longitude: float

class MedicalNeed(BaseModel):
    category: List[str]
    latitude: float
    longitude: float
    context: Optional[str] = None
    prompt: Optional[str] = None
    raw_response: Optional[str] = None

# Load environment variables
load_dotenv()

# Supabase setup
SUPABASE_URL = os.getenv("SUPABASE_URL")
SUPABASE_KEY = os.getenv("SUPABASE_KEY")
supabase = create_client(SUPABASE_URL, SUPABASE_KEY)

# Gemini setup for generation
configure(api_key=os.getenv("GEMINI_API_KEY"))

model = GenerativeModel(
    model_name="models/gemini-2.5-flash",
    generation_config={"temperature": 0.3}
)

# Local embedding model
embedder = SentenceTransformer("all-MiniLM-L6-v2")

def get_embedding(text):
    return embedder.encode(text).tolist()

def search_supabase(query: str, top_k=3):
    embed = get_embedding(query)
    embed_str = ",".join(map(str, embed))

    sql = f"""
    select id, content, metadata,
    1 - (embedding <=> '[{embed_str}]') as similarity
    from medical_docs
    order by embedding <=> '[{embed_str}]'
    limit {top_k}
    """

    response = supabase.rpc("execute_sql_from_json", {"input": {"sql": sql}}).execute()
    return response.data

def format_prompt(context_docs, note):
    context = "\n\n".join([doc["content"] for doc in context_docs])
    return f"""
You are a medical classification assistant helping 911 dispatchers.

Context:
{context}

Paramedic Note:
{note}

Classify the post-first-aid medical needs of the patient. Return the result as a Python list like this:
["burn", "trauma", "ICU"]
"""

def safe_parse_gemini_list(output):
    try:
        match = re.search(r"\[(.*?)\]", output, re.DOTALL)
        if match:
            raw_items = match.group(1)
            items = [item.strip().strip("\"'") for item in raw_items.split(",")]
            return [i for i in items if i]
        return ast.literal_eval(output)
    except Exception:
        return []

def classify_emergency(note: EmergencyNote, supabase) -> MedicalNeed:
    docs = search_supabase(note.note, top_k=5)
    prompt = format_prompt(docs, note.note)
    response = model.generate_content(prompt)

    parsed_needs = safe_parse_gemini_list(response.text.strip())

    return MedicalNeed(
        category=parsed_needs,
        latitude=note.latitude,
        longitude=note.longitude,
        context=json.dumps(docs),
        prompt=prompt,
        raw_response=response.text.strip()
    )

```

[26 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]