Spaces:
Runtime error
Agent Specs - Civil Protection Decision support system
Hard constraints:
- Tool allowlist: Only pre-approved tools in registry (registry.py)
- Geographic bounds: Liguria region only (provinces: GENOVA, SAVONA, IMPERIA, LA SPEZIA)
- Source validation: Every fact must cite approved sources with URLs and timestamps
- Performance limits: Max 4 tool calls per query, 15s timeout per tool, 3 retries with backoff
- No code execution by LLM: Only approved tools execute code, never the language model
- Deterministic validation: Fast safety checks with clear rejection reasons
- If no approved evidence β reply "Dati insufficienti dalle fonti approvate"
Agent type: LangGraph tool-calling agent with LLM router + deterministic validator.
Design rule: One public tool per source (adapter). Tools call internal services (scraping, parsing, cache, geo).
Architecture: Simple, transparent, maintainable - LLM handles intelligent routing, deterministic validator ensures safety.
Goal: Provide real-time situational awareness + historic knowledge and deterministic, auditable orchestration using only approved sources for supporting civil protection decision making in disaster management for the Liguria region.
Mission: Support emergency management and civil protection operations in Liguria by providing real-time monitoring data, emergency procedure guidance, situational awareness during emergencies, and rapid information synthesis for decision makers including civil protection operators, emergency coordinators, and regional or local authorities.
1) Orchestration (State Graph) - LLM Router + Deterministic Validator
Core Architecture: Simple 2-stage approach:
- Stage 1: LLM Router (Intelligence) β
query β LLM β {"tool": "name", "service": "specific", "params": {...}} - Stage 2: Deterministic Validator (Safety) β
LLM_proposal β validator β [execute | clarify | refuse]
Nodes:
llm_routerβ LLM analyzes query and proposes tool execution with natural language understandingvalidatorβ Deterministic safety check (geographic bounds, service health, security policy) β approve/clarify/refusetool_executionβ Execute approved tools with bounded retries, timeouts, and cachingresponse_generationβ Compose short Italian operational summary with artifacts and citationserror_handlingβ Graceful failure management with clear explanations
Flow: query β llm_router β validator β [tool_execution | clarification | refusal] β response_generation
Key Benefits:
- Natural language understanding handles ambiguity (e.g., "spezia" β "LA SPEZIA")
- Context-aware routing based on query semantics and emergency context
- Flexible tool discovery - new tools just need description in LLM prompt
- Fast, deterministic validation with clear pass/fail logic and transparent decisions
Hard constraints:
- Only call tools in
registry.py(allowlisted). - Max N tool calls per turn (e.g., 4), per-tool timeout (e.g., 15s), 3Γ retry with backoff.
- If no approved evidence β reply βDati insufficienti dalle fonti approvateβ.
2) Guardrails & Policy
Domain Allowlist (Approved Data Sources):
omirl.regione.liguria.it- OMIRL weather/hydro monitoring platformallertaliguria.regione.liguria.it- ARPAL official alerts and bulletinsautostrade.it- Highway traffic conditions and infrastructure statuscciss.mit.gov.it- National traffic coordination center- Internal RAG knowledge base - Emergency procedures and civil protection protocols (embeddings + knowledge graph)
- (Expandable as needed with additional approved sources)
Security Policies:
- No code execution by the model. Only approved tools run code.
- Provenance required: return
sources[]with URLs, timestamps, and reliability indicators. - Caching strategy: 10β15 min TTL per adapter; polite delays (β₯500 ms between DOM actions).
- PII protection: none expected; redact if present.
- Language standard: Italian for operational summaries; keep numbers/units explicit.
- Input sanitization: All user inputs validated and sanitized before processing
- Rate limiting: Per user/session limits to prevent abuse
3) Tool Interface Conventions (Flexible Standards)
Input Format (Flexible):
{
"service": "specific_service_name",
"params": {
// Tool-specific parameters - varies by tool
// Current OMIRL example for valori_stazioni serviec: province, comune, sensor_type
// Future tools may require different parameters and same for future services
}
}
Output Format (To Be Defined):
{
"summary_text": "Italian operational summary (format TBD)",
"artifacts": [
{
"type": "image|data_file",
"path": "artifacts/...",
"caption": "description"
}
],
"sources": ["https://approved.source/..."],
"metadata": { "generated_at": "ISO8601", "tool": "name" },
"warnings": ["non-fatal issues"]
}
}
Failure: never raise; return partial with warnings.
4) Tool Ecosystem (5 Main Categories)
Real-Time Monitoring Tools
A) omirl_snapshot_and_summary(params)
Purpose
Single entrypoint to gather observational data from the OMIRL platform and return an operational summary with artifacts for civil protection decision support.
Modes Each mode corresponds to a section of the omirl website.
- Tables: tabular data disaggregated by sensor type, station, and geographic information
- Map: webgis with several layers available and data for each station on whole region
- Radar: satellite imagery
Tasks Each sub task corresponds to what data extraction can be done in each section. Each section has different tasks.
- Tables - Valori Stationi: navigato to https://omirl.regione.liguria.it/#/sensorstable, one single table, scrape html table data and grab images based on sensor type then filter by provincia, comune
- Tables - Massimi di Precipitazione: navigate to https://omirl.regione.liguria.it/#/maxtable, two tables, scrape rigth html table data based on province or zone d'allerta, filter based on provincia and time, use thresholds (TODO: in internal knwoledge), grab images
- Tables - Estremi di Temperature e Vento: navigate to https://omirl.regione.liguria.it/#/maxtable, three tables, scrape rught html table data based on CittΓ , Zona d'Allerta, Zona (Costa vs Rilievi), filter based on Stazione -Tables - Livelli Idrometrici: navigate to https://omirl.regione.liguria.it/#/alertzones, eight tables (one for each Zona d'Allerta), scrape the right table based on the Zona d'ALlerta, filter using Comune and Bacino or Corso d'Acqua
- Map - Precipitazione: navigate to maps section, select spatial data layers using (climate variable + extra variable wich depends on the climate variable), save screenshot and generate summary
- Radar - Precipitazione: navigate to https://omirl.regione.liguria.it/#/animations, select ultima immagine based on climate variable extracted by query More to come for map and radar modes.
Core Capabilities and services
- Web Scraping: Extract station data and sensor readings from OMIRL web interface using Python filtering - DONE
- Map Layers: Select spatial data layers, save clean PNG screenshots using Playwright and generate descriptive text representations - TODO
- Radar Products: Capture radar products as PNG snapshots and generate text interpretations for weather analysis - TODO
- Data Filtering: Python-based filtering and analysis of scraped observational data - DONE
- OMIRL specfic Summary generation: LLM based summary generation based on scraped data - DONE, TODO: put this at the node level for when there will be results from multile tools
- Geographic resolver: intellingent province to comune resolution
Current Implementation: Currently for the omirl adapter, the agent needs to select a mode, a task or a sequence of task based on the user query and then execute the task and its related services. The modes correspond to each section of the omirl website (tables, stations, maps, radar) and to the nature of the data that can be extracted in each section. The task corresponds to actions the agent can perform in each section. For each task there is a clear set of services available. For future tools there might not be the need for multiple modes or task if they have a simpler structure.
{
"mode": "tables|station|map|radar",
"task": "valori_stazioni|massimi_precipitazione|livelli_idro",
// these are the sub tasks for the tables mode which is being implemented, other modes will have other subtasks
"filters": {
// task-specific parameters - varies by tool and service, here we have an example of those needed for "valori_stazioni" which is being implemented
// Current OMIRL example for valori_stazioni serviec: province, comune, sensor_type
// Future tools may require different parameters and same for future services
"tipo_sensore": "Precipitazione|Temperatura|UmiditΓ dell'aria|Vento", // there are more
"comune": "Genova|Rapallo|Sanremo|...", // Auto-resolved to province if needed
"provincia": "GENOVA|SAVONA|IMPERIA|LA SPEZIA", // Auto-converted to codes
"zona": null,
"area": null,
"bacino": null
},
"thresholds": { "valore_min": null },
"time_window_h": 6,
"language": "it"
}
Technical Approach
- Web scraping (no CSV downloads) from OMIRL web interface
- Python filtering for data processing and analysis
- Playwright image capture for maps and radar products
- Operational summary generation llm based and omirl specific, service-level - TODO: put at node level
- Geographic resolver for intelligent municipality-to-province resolution based on user queries
Constraints
- Domains: OMIRL only (allowlisted: omirl.regione.liguria.it)
- Resilience: retries, polite waits, graceful degradation with warnings
- Caching: short TTL (10β15 min) to reduce load and stabilize output
- Provenance: URLs and timestamps are mandatory for all data sources
Constraints
- Domains: OMIRL only (allowlisted: omirl.regione.liguria.it)
- Resilience: retries, polite waits, graceful degradation with warnings
- Caching: short TTL (10β15 min) to reduce load and stabilize output during emergency operations
- Provenance: URLs and timestamps are mandatory for all data sources
B) bulletin_scraper(params)
Purpose: Retrieve official emergency bulletins and alerts from ARPAL and civil protection sources
- ARPAL Bulletins: Weather warnings, hydrogeological alerts with severity classification
- Civil Protection Alerts: Emergency notifications, evacuation orders, coordination instructions
- Automated Risk Assessment: Severity level classification and impact analysis
C) traffic_monitor(params)
Purpose: Real-time traffic and critical infrastructure status monitoring
- Highway Status: A10, A12, A26 traffic conditions and travel times
- Emergency Closures: Road closures, alternative routes, infrastructure damage
- Critical Infrastructure: Tunnel, bridge, port operational status
News & Information Tools
D) news_scraper(params)
Purpose: Monitor regional news sources for emergency-related information and public communications
- Local News: Emergency-related articles from regional sources with relevance scoring
- Official Communications: Municipal and regional press releases and announcements
- Social Media Monitoring: Official emergency management social media accounts
RAG & Knowledge Tools
E) rag_emergency_procedures(params)
Purpose: Retrieve emergency procedures and protocols from internal knowledge base
- Procedure Lookup: Search emergency response protocols by scenario type
- Legal Framework: Civil protection laws, regulations, and compliance requirements
- Best Practices: Historical incident response analysis and lessons learned
- Contact Directory: Emergency contacts, coordination centers, and communication protocols
Knowledge Sources: Civil protection emergency plans, municipal emergency procedures, regional coordination protocols, historical incident reports, training materials and SOPs
F) knowledge_graph_query(params)
Purpose: Structured knowledge queries for complex emergency scenarios
- Entity Relationships: Connect geographic areas, risk factors, and available resources
- Scenario Modeling: Query similar historical situations and response patterns
- Resource Mapping: Available emergency resources by geographic area and capability
- Multi-factor Risk Assessment: Comprehensive risk evaluation incorporating multiple data sources
5) Utilities & Implementation Advantages
Core Utilities:
services/web/browser.pyβ Playwright page setup, cookie dismissal, viewport management, intelligent waitsservices/text/formatters.pyβ Italian summary templates, unit helpers, emergency terminologyservices/data/artifacts.pyβ Artifact management, file handling, metadata preservationservices/media/screenshot.pyβ Screenshot capture, image processing, visual analysis- Additional utilities for caching, geographic operations, and data validation
LLM Router Architecture Benefits:
Simplicity & Maintainability:
- Single LLM call for routing
- Clear failure points - either LLM routing fails or validation fails (easy debugging)
- New tools integration - just add description to LLM prompt, no code changes required
Operational Excellence:
- Context awareness - LLM understands emergency context, urgency levels, and operational priorities
- Natural language support - handles Italian regional terminology and ambiguous queries natively
- Flexible queries - processes complex, multi-part requests naturally without rigid parameter structures
- Transparent decisions - every routing decision is explainable with clear reasoning
Performance & Reliability:
- Fast deterministic validation with predictable response times for safety checks
- Error transparency - clear explanations when requests cannot be fulfilled with specific guidance
- Geographic intelligence - natural understanding of Liguria region geography and administrative boundaries
- Emergency response optimization - prioritizes critical requests and maintains service availability during high-load scenarios