SwarmUp
An AI in charge of a cascading blackout
An autonomous agent that takes in hundreds of signals, decides which ones matter, splits a fleet that is never big enough, phones the people in charge and replans when the situation changes.
We built it in 48 hours on the real streets of Getafe. A human operator can step in at any moment.
Animated replica of the real interface. Pause, restart or inject a fault with the buttons in the top bar. On narrow screens, swipe to see all of it.
Why a blackout
HappyRobot suggested floods or wildfires. We went off the list: last year's blackout was still fresh in our minds, and so was how badly emergency services struggled.
HackSpain 2026 brought together 250 developers and five startups in Madrid, organized by Exponential. We picked the HappyRobot challenge: can an AI manage a crisis?
There are always fewer units than problems
That's demand against the available fleet in every run. There's never enough for everyone, so the agent has to prioritize and explain why.
Hospital without power
Diesel for the generators
It can't last more than 8 minutes off the grid.
Traffic lights out
Police to direct traffic
Otherwise nothing we send gets there.
Life support at home
Portable generator to the door
Someone calls: a relative depends on a machine.
Telecom tower
Generator, now
Without batteries, the agent loses its phone line.
Underneath there are two graphs: a topology graph, with which hospitals, plants and towers depend on each substation, and a solutions graph, with its rules and weights. Every run draws a different crisis from a seed, so nothing is scripted.
Two hours of crisis, compressed into minutes
The dashboard mid-crisis: substations going down, hospitals without power and units routed through the real streets.

How the agent thinks
Every tick goes through three layers. The cheap, deterministic part runs first; the model only steps in when there's real thinking to do.
Rules, around 1 ms
Detect
Filters out the noise and computes priorities. It only wakes the LLM when something actually changes: a threshold crossed, a failed arrival or a rejected call.
LLM, 8 to 20 s
Decide
Gets the world, the rules, the topology and similar past incidents. Returns a structured plan: what it drops, what it does and who it calls.
Hard rules
Act
Rules veto anything that breaks a constraint and send the reason back to the model. Whatever passes gets executed: units on the move and calls.
The LLM proposes, the rules decide.
It never freezes
If the model doesn't answer in time, a contingency playbook takes over and the simulation keeps going.
It learns from every crisis
Every resolved incident is stored in Chroma and retrieved in the next deliberation. The agent cites the past incidents it used.
A human always at hand
From the console, an operator can inject events, pause or correct the plan at any time.
And it makes real phone calls
Decisions don't stay on the screen. The agent calls the people in charge through HappyRobot, with no fixed script, and what they answer changes the plan.
El Bercial is off the grid. We're sending the generator, arriving in about five minutes. Do you accept?
I accept.
How many minutes do you need to bring the backup online?
Ten.Logged: 10 min to bring the backup online
It confirms what it understood, hangs up, summarizes the call and the result goes back to the agent. If someone says "in half an hour", it understands 30 minutes.
- The agent launches the mission via webhook
- HappyRobot calls the contact and follows the promptA queue spreads calls across a pool of contacts.
- The AI summarizes the call as JSON
- It's sent to a Cloudflare Worker with Hono and D1With no cloud of our own, the Worker acted as a tiny events backend.
- The backend reads it and reactsA no or a delay triggers a replan.
The provider the organizers pointed us to wouldn't connect over SIP. In the early hours of Friday, we hooked up our own IP phone, pointed the SIP trunk at HappyRobot and started making real calls. The head start lasted until the other teams hit the same wall and the organizers enabled another provider.
Built in a weekend, with tests
| Frontend | React 19, Vite 8 and MapLibre GL, with units routed through real OpenStreetMap streets |
|---|---|
| Backend | Express 4 and zod, strict TypeScript monorepo on Node 24 |
| LLM | deepseek-v4-flash via Helmcode, with the OpenAI SDK so the model can be swapped |
| Memory | Chroma, with 72 curated incidents plus the wrap-up of every run |
| Telephony | HappyRobot with a call queue and per-contact balancing |
| Return path | Cloudflare Worker with Hono and D1 |
| Quality | oxlint, 162 tests and CI on GitHub Actions |