smart_emergency / server /calls.py
rishi38's picture
Upload folder using huggingface_hub
4b98131 verified
"""911 call transcript generator for Dispatch911."""
import random
from dataclasses import dataclass
from typing import List, Optional
from .city import City
# Call templates
TEMPLATES = [
# FIRE
{"type": "fire", "sev": 1, "vehicle": "fire",
"text": "Hi, I think I see some smoke coming from behind {landmark}. It might be nothing but thought I should call."},
{"type": "fire", "sev": 2, "vehicle": "fire",
"text": "Yeah there's a small fire in a dumpster near {landmark} on {street}. It's not spreading but it's pretty smoky."},
{"type": "fire", "sev": 3, "vehicle": "fire",
"text": "There's a fire at {address}! Flames coming out a window on the second floor. I don't think anyone's inside but I'm not sure."},
{"type": "fire", "sev": 4, "vehicle": "fire",
"text": "Oh god, the whole kitchen is on fire at {address}! My kids are upstairs — please send someone NOW!"},
{"type": "fire", "sev": 4, "vehicle": "fire",
"text": "Building's on fire on {street} near {landmark}! People are yelling from the windows, please hurry!"},
{"type": "fire", "sev": 5, "vehicle": "fire",
"text": "There's a massive fire — the whole block near {landmark} is burning. Multiple buildings involved, I can see people trapped. Send everything you've got!"},
# MEDICAL
{"type": "medical", "sev": 1, "vehicle": "ambulance",
"text": "Hello, my neighbor fell and hurt her ankle at {address}. She's conscious and talking but can't walk."},
{"type": "medical", "sev": 2, "vehicle": "ambulance",
"text": "Someone fainted at {landmark}. They're breathing okay now but look really pale. We're on {street}."},
{"type": "medical", "sev": 3, "vehicle": "ambulance",
"text": "There's a man having chest pains at {address}. He's sweating a lot and says his arm feels numb."},
{"type": "medical", "sev": 4, "vehicle": "ambulance",
"text": "My husband just collapsed and he won't wake up! He's breathing weird. We're at {address}, please hurry!"},
{"type": "medical", "sev": 4, "vehicle": "ambulance",
"text": "Someone's not breathing at {landmark}! A bystander is doing CPR. Please send an ambulance to {street} immediately!"},
{"type": "medical", "sev": 5, "vehicle": "ambulance",
"text": "There's been some kind of mass incident at {landmark} — multiple people down, some not moving. We need everything, {street} entrance."},
# CRIME
{"type": "crime", "sev": 1, "vehicle": "police",
"text": "I'd like to report a shoplifter at {landmark} on {street}. They already left but I got a good look."},
{"type": "crime", "sev": 2, "vehicle": "police",
"text": "There's a break-in happening right now at {address}. I can see someone climbing through a window from across the street."},
{"type": "crime", "sev": 3, "vehicle": "police",
"text": "There's a fight outside {landmark} on {street}. Looks like 3-4 people involved, getting pretty violent."},
{"type": "crime", "sev": 3, "vehicle": "police",
"text": "I just got mugged near {landmark}! The guy ran towards {cross_street}. He had a knife."},
{"type": "crime", "sev": 4, "vehicle": "police",
"text": "I think I heard gunshots near {address}! People are running. I'm hiding inside {landmark}, please send help!"},
{"type": "crime", "sev": 5, "vehicle": "police",
"text": "Active shooter at {landmark}! Multiple shots fired, people running everywhere. Send everyone NOW!"},
# ACCIDENT
{"type": "accident", "sev": 2, "vehicle": "ambulance",
"text": "Fender bender on {street} near {landmark}. No injuries but the cars are blocking the road."},
{"type": "accident", "sev": 3, "vehicle": "ambulance",
"text": "Car accident at {street} and {cross_street}. One driver looks hurt, holding their neck. Other car's smoking."},
{"type": "accident", "sev": 3, "vehicle": "ambulance",
"text": "A cyclist got hit by a car near {landmark}. They're on the ground, conscious but bleeding from the head."},
{"type": "accident", "sev": 4, "vehicle": "ambulance",
"text": "Bad crash on {street}! Car flipped over near {landmark}. Driver's trapped inside, not responding!"},
{"type": "accident", "sev": 4, "vehicle": "ambulance",
"text": "Pedestrian hit by a truck at {cross_street} near {landmark}. They're not moving. There's blood everywhere."},
{"type": "accident", "sev": 5, "vehicle": "ambulance",
"text": "Multi-car pileup on {street} near {landmark}! At least 5 cars, people screaming, I can smell gas leaking. Send fire too!"},
]
@dataclass
class Call:
"""A single incoming 911 call with hidden ground truth."""
call_id: str
event_id: str
origin_node_id: str
origin_node_name: str
emergency_type: str
severity: int
required_vehicle_type: str
is_duplicate_of: Optional[str]
transcript: str
def generate_call(
city: City,
call_number: int,
active_events: dict,
duplicate_prob: float,
rng: random.Random,
next_event_counter: int,
) -> tuple:
"""
Generate one 911 call.
Returns (Call, new_event_counter).
"""
node_ids = list(city.nodes.keys())
# Decide if duplicate
is_dup = False
dup_event_id = None
dup_event = None
if active_events and rng.random() < duplicate_prob:
dup_event_id = rng.choice(list(active_events.keys()))
dup_event = active_events[dup_event_id]
is_dup = True
if is_dup and dup_event is not None:
etype = dup_event["type"]
sev = dup_event["severity"]
vtype = dup_event["vehicle"]
origin = dup_event["node_id"]
event_id = dup_event_id
else:
# Pick a random template
tmpl = rng.choice(TEMPLATES)
etype = tmpl["type"]
sev = tmpl["sev"] + rng.choice([-1, 0, 0, 0, 1])
sev = max(1, min(5, sev))
vtype = tmpl["vehicle"]
# Pick origin node (prefer residential/commercial)
preferred = [n for n in node_ids if city.nodes[n].node_type in ("residential", "commercial")]
origin = rng.choice(preferred) if preferred else rng.choice(node_ids)
event_id = f"EVT-{next_event_counter:04d}"
next_event_counter += 1
# Build transcript
node = city.nodes[origin]
neighbours = list(city.edges.get(origin, {}).keys())
cross = city.nodes[rng.choice(neighbours)].street if neighbours else "unknown road"
# Pick a template matching the type
matching = [t for t in TEMPLATES if t["type"] == etype]
tmpl = rng.choice(matching)
address = f"{rng.randint(100, 999)} {node.street}"
text = tmpl["text"].format(
landmark=node.name,
street=node.street,
address=address,
cross_street=cross,
)
call = Call(
call_id=f"CALL-{call_number:04d}",
event_id=event_id,
origin_node_id=origin,
origin_node_name=node.name,
emergency_type=etype,
severity=sev,
required_vehicle_type=vtype,
is_duplicate_of=dup_event_id if is_dup else None,
transcript=text,
)
print(call)
return call, next_event_counter