Updates, big updates
incident_correlator.py — full rewrite: always runs on every call, fetches all active incidents cross-type, fast path collects all talkgroup matches and disambiguates by unit/vehicle overlap → location proximity → embedding, new location proximity path, slow path requires location corroboration, "Auto:" stripped from titles, "auto-generated" tag added, units/vehicles now accumulated on update intelligence.py — resolved field in GPT schema, returned as 5th value upload.py — both pipelines unpack 5-tuple, always call correlate, auto-resolve on resolved=True summarizer.py — stale sweep runs each tick, resolves incidents idle for 90+ minutes config.py — correlation_window_hours=2, embedding_similarity_threshold=0.93, location_proximity_km=0.5, incident_auto_resolve_minutes=90
This commit is contained in:
@@ -22,6 +22,7 @@ Schema:
|
||||
"vehicles": [vehicle descriptions mentioned, e.g. "Hyundai Tucson", "black sedan"],
|
||||
"units": [unit IDs or officer numbers mentioned, e.g. "Unit 511", "Car 4"],
|
||||
"severity": one of "minor" | "moderate" | "major" | "unknown",
|
||||
"resolved": true if this call explicitly signals the incident is over ("Code 4", "in custody", "all clear", "fire out", "patient transported", "GOA", "scene clear", "10-42", "negative contact", "clear the scene"), false otherwise,
|
||||
"transcript_corrected": "corrected full transcript string, or null if no corrections needed"
|
||||
}}
|
||||
|
||||
@@ -48,14 +49,15 @@ async def extract_tags(
|
||||
system_id: Optional[str] = None,
|
||||
segments: Optional[list[dict]] = None,
|
||||
node_id: Optional[str] = None,
|
||||
) -> tuple[list[str], Optional[str], Optional[str], Optional[dict]]:
|
||||
) -> tuple[list[str], Optional[str], Optional[str], Optional[dict], bool]:
|
||||
"""
|
||||
Extract incident tags, type, location, and corrected transcript via GPT-4o mini.
|
||||
Extract incident tags, type, location, corrected transcript, and closure signal via GPT-4o mini.
|
||||
Geocodes the extracted location string via Nominatim using the node's position as bias.
|
||||
|
||||
Returns:
|
||||
(tags, primary_type, location_str, location_coords)
|
||||
where location_coords is {"lat": float, "lng": float} or None.
|
||||
(tags, primary_type, location_str, location_coords, resolved)
|
||||
where location_coords is {"lat": float, "lng": float} or None,
|
||||
and resolved is True when the transcript signals incident closure.
|
||||
|
||||
Side-effect: updates calls/{call_id} in Firestore with tags, location,
|
||||
location_coords, vehicles, units, severity, transcript_corrected; also stores embedding.
|
||||
@@ -70,6 +72,7 @@ async def extract_tags(
|
||||
vehicles: list[str] = result.get("vehicles") or []
|
||||
units: list[str] = result.get("units") or []
|
||||
severity: str = result.get("severity") or "unknown"
|
||||
resolved: bool = bool(result.get("resolved", False))
|
||||
transcript_corrected: Optional[str] = result.get("transcript_corrected") or None
|
||||
|
||||
if incident_type in ("unknown", "other", ""):
|
||||
@@ -112,7 +115,7 @@ async def extract_tags(
|
||||
f"tags={tags}, location={location!r}, coords={location_coords}, severity={severity}, "
|
||||
f"corrected={transcript_corrected is not None}"
|
||||
)
|
||||
return tags, incident_type, location, location_coords
|
||||
return tags, incident_type, location, location_coords, resolved
|
||||
|
||||
|
||||
async def _geocode_location(
|
||||
|
||||
Reference in New Issue
Block a user