AI Incident Triage with RAG and Slack Notifications
Triage incoming incidents with a RAG pipeline that grounds Gemini in your ops knowledge base and posts triage steps to Slack.
Monitor river discharge forecasts with Open-Meteo, write flood risk bulletins with a local Ollama LLM, and alert Slack only when a river is at risk.
Floods rarely arrive without warning: global hydrological models such as GloFAS forecast river discharge days ahead, and the forecasts are openly available. What's usually missing is the last mile, someone checking the numbers every few hours and telling the right people in plain words. This blueprint automates that last mile. It was built for the Grijalva and Usumacinta rivers in Tabasco, Mexico, a region that floods often, but it works for any river point on the map.
The bulletin is written by a model running on your own Ollama server, so the LLM call has no hosted API charge, keeps working where cloud APIs are blocked or too expensive, and lets you swap models with a single input.
check_rivers (io.kestra.plugin.core.flow.Loop) iterates over the stations input with concurrencyLimit: 1.fetch_forecast (io.kestra.plugin.core.http.Request) calls the Open-Meteo Flood API for today's modeled discharge and the 7-day maximum ensemble forecast. The loop's outputs use jq to extract today's value, the forecast peak and its date, and compute at_risk: the peak reaches alert_m3s, or it is at least rise_alert_pct percent above today.write_bulletin (io.kestra.plugin.ai.completion.ChatCompletion with the io.kestra.plugin.ai.provider.Ollama provider) turns the numbers into a short bulletin in the language you choose, using only the data it was given.save_bulletin (io.kestra.plugin.core.storage.Write) stores the bulletin and a data table as a markdown file in internal storage.alert_if_needed (io.kestra.plugin.core.flow.If) posts the bulletin to Slack with io.kestra.plugin.slack.notifications.SlackIncomingWebhook only when at least one point is at risk; otherwise all_clear logs a one-line summary.errors branch posts a separate Slack alert if the API or the model call fails.every_six_hours Schedule trigger runs the flow at minute 0 of every sixth hour. It ships disabled, so you can test manually first.ollama_endpoint, with the chosen model pulled (ollama pull gemma3:4b).flood-api.open-meteo.com. No API key is needed for non-commercial use; commercial use requires an Open-Meteo API plan.SLACK_WEBHOOK_URL: Slack incoming webhook that receives at-risk bulletins and failure alerts (required for alerts; the all-clear path doesn't use it).| Input | Type | Default | Purpose |
|---|---|---|---|
stations |
JSON | Usumacinta and Grijalva (Tabasco, MX) | River points to watch: name, latitude, longitude, alert_m3s |
rise_alert_pct |
INT | 50 |
Non-negative. Also flag a point when the 7-day peak is at least this % above today's modeled discharge |
bulletin_language |
SELECT | English |
English, Spanish, Portuguese or French |
model |
STRING | gemma3:4b |
Ollama model that writes the bulletin |
ollama_endpoint |
STRING | http://localhost:11434 |
Ollama base URL (http://host.docker.internal:11434 when Kestra runs in Docker) |
The default alert_m3s values are examples. Replace them with the alert levels your water authority publishes for each point. Open-Meteo snaps coordinates to its ~5 km river grid, so test a few nearby coordinates and keep the one whose discharge matches the main channel.
{{ outputs.check_rivers.outputs }}: one entry per point (each under .outputs, sort by .item.iteration for input order) with name, today_m3s, peak_m3s, peak_date, alert_m3s and at_risk.{{ outputs.write_bulletin.textOutput }}: the bulletin text.{{ outputs.save_bulletin.uri }}: the markdown bulletin with its data table, downloadable from the execution's Outputs tab.ollama pull gemma3:4b.SLACK_WEBHOOK_URL secret.alert_m3s below the current discharge.every_six_hours trigger.This is a decision-support tool built on model forecasts, not an official warning system. Always follow your national water authority and civil protection alerts.
