copilot-swe-agent[bot]
refactor: extract default location fallback to constant in triage_agent
bc0d3ba unverified | from __future__ import annotations | |
| import logging | |
| import uuid | |
| from datetime import datetime | |
| from typing import Any, List, Optional | |
| from schemas.incident import EvidenceItem, Incident, IncidentStatus, Priority | |
| from schemas.signal import NormalizedSignal, SignalType | |
| from skills.calculate_confidence import calculate_confidence | |
| from skills.classify_priority import classify_priority | |
| logger = logging.getLogger(__name__) | |
| _PRIORITY_ORDER = {Priority.P0: 0, Priority.P1: 1, Priority.P2: 2, Priority.P3: 3} | |
| _DEFAULT_LOCATION_FALLBACK = "Barrio Santa Ana" | |
| class TriageAgent: | |
| def __init__(self, session_id: str, vllm_client: Any = None) -> None: | |
| self.session_id = session_id | |
| self.vllm_client = vllm_client | |
| async def run(self, signals: List[NormalizedSignal]) -> List[Incident]: | |
| logger.info("TriageAgent: creating incidents from %d signals", len(signals)) | |
| incidents: List[Incident] = [] | |
| groups: dict = {} | |
| for signal in signals: | |
| key = (signal.signal_type, signal.location or "unknown") | |
| groups.setdefault(key, []).append(signal) | |
| for (signal_type, location), group_signals in groups.items(): | |
| priority = await classify_priority(group_signals[0], self.vllm_client) | |
| total_affected: Optional[int] = None | |
| for s in group_signals: | |
| if s.affected_people: | |
| total_affected = (total_affected or 0) + s.affected_people | |
| confidence = await calculate_confidence(group_signals) | |
| title = self._make_title(signal_type, location) | |
| description = self._make_description(signal_type, location, group_signals, total_affected) | |
| coords = next((s.coordinates for s in group_signals if s.coordinates), None) | |
| evidence = [ | |
| EvidenceItem( | |
| report_id=s.source_report_id, | |
| modality=s.modality, | |
| description=s.description[:150], | |
| ) | |
| for s in group_signals | |
| ] | |
| incident = Incident( | |
| id=str(uuid.uuid4()), | |
| session_id=self.session_id, | |
| title=title, | |
| description=description, | |
| priority=priority, | |
| status=IncidentStatus.NEW, | |
| signal_ids=[s.id for s in group_signals], | |
| evidence=evidence, | |
| location=location if location != "unknown" else None, | |
| coordinates=coords, | |
| affected_people=total_affected, | |
| confidence=confidence, | |
| created_at=datetime.utcnow(), | |
| updated_at=datetime.utcnow(), | |
| ) | |
| incidents.append(incident) | |
| incidents.sort(key=lambda x: _PRIORITY_ORDER.get(x.priority, 99)) | |
| logger.info("TriageAgent: created %d incidents", len(incidents)) | |
| return incidents | |
| def _make_title(self, signal_type: SignalType, location: str) -> str: | |
| type_labels = { | |
| SignalType.PERSON_TRAPPED: "Persona(s) Atrapada(s)", | |
| SignalType.MEDICAL_EMERGENCY: "Emergencia Médica", | |
| SignalType.STRUCTURAL_DAMAGE: "Daño Estructural", | |
| SignalType.FLOOD: "Inundación", | |
| SignalType.FIRE: "Incendio", | |
| SignalType.MISSING_PERSON: "Persona Desaparecida", | |
| SignalType.RESOURCE_REQUEST: "Solicitud de Recursos", | |
| SignalType.SAFE_STATUS: "Reporte de Seguridad", | |
| SignalType.UNKNOWN: "Incidente Desconocido", | |
| } | |
| label = type_labels.get(signal_type, "Incidente") | |
| loc = location.title() if location and location != "unknown" else _DEFAULT_LOCATION_FALLBACK | |
| return f"{label} — {loc}" | |
| def _make_description( | |
| self, | |
| signal_type: SignalType, | |
| location: str, | |
| signals: List[NormalizedSignal], | |
| affected: Optional[int], | |
| ) -> str: | |
| parts = [f"Tipo: {signal_type.value.replace('_', ' ').title()}."] | |
| if location and location != "unknown": | |
| parts.append(f"Ubicación: {location}.") | |
| if affected: | |
| parts.append(f"Personas afectadas estimadas: {affected}.") | |
| parts.append(f"Basado en {len(signals)} señal(es) recibida(s).") | |
| if signals: | |
| parts.append(f"Reporte más reciente: {signals[-1].description[:100]}.") | |
| return " ".join(parts) | |