← Back to events
SwarmUp by 540HackSpain 2026, Madrid. HappyRobot challenge

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

110-140 %

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.

SwarmUp dashboard mid-crisis: a list of 53 sites with 18 critical, a map of Getafe with units in transit, the agent feed with accepted calls and replans, and the fleet at the bottom.
On the left, sites ranked by criticality. In the middle, the map with every unit and its route. On the right, the agent feed with decisions, calls and replans. At the bottom, the fleet: crews, tankers, generators and police.

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.

  1. 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.

  2. 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.

  3. 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.

Real call (in Spanish), 1 minute, El Bercial hospital

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.

  1. The agent launches the mission via webhook
  2. HappyRobot calls the contact and follows the promptA queue spreads calls across a pool of contacts.
  3. The AI summarizes the call as JSON
  4. It's sent to a Cloudflare Worker with Hono and D1With no cloud of our own, the Worker acted as a tiny events backend.
  5. 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

14,000lines of TypeScript
162tests, all green
83commits in 3 days, all through PRs
48 hfrom Friday to Sunday
FrontendReact 19, Vite 8 and MapLibre GL, with units routed through real OpenStreetMap streets
BackendExpress 4 and zod, strict TypeScript monorepo on Node 24
LLMdeepseek-v4-flash via Helmcode, with the OpenAI SDK so the model can be swapped
MemoryChroma, with 72 curated incidents plus the wrap-up of every run
TelephonyHappyRobot with a call queue and per-contact balancing
Return pathCloudflare Worker with Hono and D1
Qualityoxlint, 162 tests and CI on GitHub Actions