Project Info
This project did not submit a demo video on Devpost.
Inspiration
I served in the Navy. One of my roles was damage control: keeping the ship alive when fire and flooding hit at the same time. Let me tell you what that actually feels like. You are in a steel passageway. The lights are strobing. Smoke is filling the space faster than you can breathe through it, water is rising past your boots, and a general alarm is screaming so loud you cannot hear the person next to you. Somewhere on that ship is a sailor's son, a sister, somebody's whole world, and the only thing standing between them and the sea is whether the people on the bridge can understand what is happening fast enough to act. And here is the brutal truth I lived: the enemy was never a lack of information. It was the flood of it. Bilge alarms, thermal sensors, smoke detectors, and frantic radio reports all screaming at once, while we tracked the fight for a billion-dollar warship and the lives aboard it on a grease pencil and a plexiglass board. One shared board. One fragile source of truth. Every update erased the last one. On a calm day with a clean log, roughly 1% of hand-entered data is wrong. Now add smoke, heat, and adrenaline. The studies are blunt about where this leads: $$P(\text{accident} \mid \text{human error}) \approx 0.75\text{ to }0.96 \quad \text{(Allianz AGCS Safety & Shipping Review)}$$ Three out of four marine disasters trace back not to broken steel, but to a human being who was handed too much noise and too little time. I left the Navy. I never left that feeling. CrisisRoom is the second brain I wish we'd had on the deck.
What it does
CrisisRoom turns crisis chaos into one clear, verified plan by running a live incident through a swarm of specialist AI agents that think together, the way a trained damage-control team does: Hazard Intelligence: ranks flood, fire, and smoke severity and localizes each threat to a specific compartment. Damage Control: assesses watertight integrity, bilge pumping capacity, fire suppression readiness, and structural risk, then recommends containment actions. Response Coordination: turns confirmed hazards and containment status into prioritized, sequenced response tasks with owner roles. Orchestrator: threads each agent's output into the next and synthesizes a single bridge brief a human can act on in seconds. Integrations Fetch AI: Four collaborating uAgents (Orchestrator, Hazard, Response, Advisory) run in a Bureau with real agent-to-agent messaging, powered by ASI:One and registered on Agentverse. The agent fleet + ASI:One LLM drive the entire crisis pipeline. Redis: Hits all three pillars: Redis for agent long-term memory, vector search (RediSearch KNN), and context retrieval (Streams + hybrid search). Redis is the agents' brain, not a cache. Arize: OpenInference tracing on every LLM call plus an LLM-as-judge scoring safety_policy/groundedness that surfaced and let us fix unsafe outputs. Observability that measurably improved the app. (https://app.arize.com/organizations/QWNjb3VudE9yZ2FuaXphdGlvbjo0NDc0NTptcFpJ/spaces/U3BhY2U6NDcyOTg6MVJjRg==/projects/TW9kZWw6ODQ3Mjg4MDQwMzo3bU1F?traceViewId=__arize_default&timeZoneA=America%2FLos_Angeles&selectedTab=llmTracing&startA=1781420400000&endA=1782039599999&envA=tracing&timeRangeKeyA=custom&modelType=generative_llm) Deepgram: Nova-3 STT + Aura-2 TTS as a bidirectional, hands-free crisis voice dispatcher. Voice is the core hands-free command interface, not tacked on. Orkes: AgentSpan durably generates the brief's top_risks and recommended_actions via two chained agent executions. Durable risk/action planning inside the live pipeline. The Token Company: Built CRISP, a reversible, query-aware context-compression framework plus an agentic compressor, with research docs and benchmarks. Novel research cutting LLM context cost. (https://github.com/uc-berkeley-ai-hackathon-2026/crisis-room/blob/main/docs/crisp-technical-deck.html) Sentry: Live sentry_sdk with PII scrubbing and incident-tagged error capture across the FastAPI backend and Next.js frontend. Error monitoring from day one. (https://carnegie-mellon-university-d3.sentry.io/issues/?project=4511600565420032) Anthropic: Built the whole project with Claude Code, tackling emergency response β a high-stakes "shift what's possible for people" domain. Claude Code as one of the primary development tool. Midjourney: 8 cinematic deck backgrounds plus the in-app vessel hazard schematic (HazardMap.tsx, labeled "Midjourney render"). Generated imagery for both product UI and pitch. (https://github.com/uc-berkeley-ai-hackathon-2026/crisis-room/blob/main/apps/web/public/vessel-schematic.png) Cognition (Devin): Used Devin as an AI coding agent during the build, especially via the cloud. AI-assisted coding combined with Claude Code.
How we built it
Frontend and backend: a Next.js dashboard and a typed FastAPI service over REST and WebSocket. It runs mock-first with zero API keys, then lights up as each integration connects. A judge can clone it and watch it work in one command. Agents: four Fetch.ai uAgents in a single Bureau, discoverable on Agentverse and collaborating in-process, with ASI:One as the reasoning LLM behind every one of them. Memory: Redis as the primary store, not a cache, in three tiers: Redis Iris for long-term semantic memory, RedisVL vector search (HNSW, cosine) for the live session, and a lexical fallback. Streams carry real-time coordination events. Durable planning: Orkes AgentSpan runs risk_assessor then action_planner as chained, durable executions, so the highest-stakes part of the brief is orchestrated and observable. Observability and safety: every LLM call is traced to Arize, and an LLM-as-judge scores each output on safety_policy and groundedness, writing the verdict back onto the exact span. CRISP: a reversible, query-aware compression framework we built and benchmarked to shrink crisis context while protecting the numbers and entities that decide whether someone lives.
Challenges we ran into
Cross-process uAgent messaging needs the Fetch.ai Almanac network, which was unreachable for us. We solved it with an in-process Bureau that still registers on Agentverse for discoverability. Early prompts occasionally implied an alert "had been sent." In a real crisis, that single false sentence kills people. Our Arize safety evaluator caught it, and we drove the failure rate down until it was gone. Failed durable executions leaked raw error text into the brief. We fixed the parser to fail safe and fall back cleanly, because a wrong answer dressed as a confident one is the most dangerous output a crisis tool can produce. We made Redis, ASI:One, RediSearch, and voice all optional with deterministic fallbacks, because the moment you need this system most is the moment the network is on fire too.
Accomplishments we're proud of
A genuinely collaborating agent swarm, not four disconnected prompts wearing a trench coat. Redis used as an AI-native brain, with Streams and vector search, holding sub-20ms latency at scale. Safety we can actually measure, through an LLM-as-judge wired onto live traces, instead of hoping the model behaved. A system that runs anywhere, with zero keys, in one command, so the people who need it are never blocked by a missing credential. Most of all: we took the worst day of my old job and built something so the next damage controlman has a fighting chance the rest of us did not.
What we learned
Observability is a safety feature, not an afterthought. If you cannot measure whether your AI is safe, it is not. Redis is an AI-native database, not just a cache. Human-in-the-loop is not a limitation. It is the product. Trust is the feature people are actually buying. Build the fallbacks first. In a real crisis, the happy path is the first thing to burn.
FloodFire CrisisRoom
FloodFire CrisisRoom is a multi-agent shipboard emergency command dashboard that ingests flooding, fire, smoke, and crew-report signals, verifies them, creates response tasks, and drafts crew/passenger advisories for bridge approval.
This is a hackathon MVP scaffold. It is mock-first, typed, and runnable without external API keys.
π Redis Beyond Caching - Prize Track
Redis is the intelligent memory layer powering multi-agent crisis coordination:
- β Vector Search: Semantic memory retrieval (RediSearch + embeddings)
- β Real-Time Streams: Agent coordination via Redis Streams
- β AI Memory: Persistent agent context across sessions
- β Hybrid Search: Keyword + vector similarity fusion
Not a cache - Redis is the primary data store for agent memories, event sourcing, and semantic search.
π See: README_REDIS.md | REDIS_SHOWCASE.md | REDIS_ARCHITECTURE.md
Hackathon Prize-Track Strategy
- AI agents: clear agent boundaries for Commander, Flood Analyst, Fire Analyst, Verification, Response Planner, and Public Information.
- Real-time data: connector stubs and simulated shipboard sensors for bilge alarms, pump-room water rise, Engine Room thermal alarms, smoke reports, and crew field reports.
- Voice: Deepgram-ready voice report interface with manual fallback.
- Memory and coordination: Redis placeholder for incident memory, dedupe, and agent state.
- Redis beyond caching: Redis stores durable crisis memory, stream-based operational events, and agent context retrieval. If Redis Stack/RediSearch is available, the app reports vector-search readiness; otherwise it uses lexical retrieval over Redis memory hashes.
- Observability: Arize and Sentry placeholders for tracing, evaluation, and reliability.
- Human-centered safety: crew/passenger advisories are drafts only and require bridge/human approval.
Architecture
apps/web Next.js dashboard
-> typed API client
-> FastAPI REST + WebSocket
-> route modules
-> services: simulation, verification, agents, tasks, alert drafting
-> in-memory store by default
-> optional Redis and external connector stubs
Setup
cp .env.example .env
Put real secrets only in .env. The committed .env.example intentionally contains placeholders.
Minimum keys for the full demo:
ASI_ONE_API_KEYβ Fetch.ai ASI:One LLMAGENTVERSE_API_KEYβ Agentverse mailbox for discoverable uAgents
Optional keys:
ASI_ONE_MODEL: ASI:One model name, defaults toasi1-mini.ANTHROPIC_API_KEY: future Claude agent reasoning.REDIS_URL: local or hosted Redis connection string.REDIS_ACCOUNT_KEY,REDIS_API_KEY: hosted Redis account/API access if your Redis provider requires them.DEEPGRAM_API_KEY: voice transcription.BROWSERBASE_API_KEY: official-source browser checks.ARIZE_API_KEY+ARIZE_SPACE_ID: LLM tracing/evaluation (see Arize Observability below).SENTRY_DSN: frontend/backend error monitoring.NASA_FIRMS_MAP_KEY: real active fire detections.
Quick Start
Run these from the repo root (crisis-room/).
1. One-time install
npm install
cd api && python3 -m venv .venv && . .venv/bin/activate && pip install -e .
2. Start the app (terminal 1)
npm run dev
Starts:
- Frontend: http://localhost:3000/dashboard
- API: http://localhost:8000
Leave this terminal running.
3. Start Fetch.ai agents (terminal 2, optional)
Required for the Agentverse sponsor track. The dashboard works without this if ASI_ONE_API_KEY is set β ASI:One is called directly from FastAPI.
npm run dev:agents
Starts all four agents in a single uAgents Bureau (one process, served on :8100).
They register on Agentverse (discoverable) and communicate with each other in-process
(see Agent-to-agent communication):
| Agent | Role |
|---|---|
| FloodFire Crisis Orchestrator | Coordinates the specialist swarm and synthesizes the bridge situation brief |
| Hazard Intelligence Agent | Assesses flood/fire/smoke indicators, localizes to compartments, ranks severity |
| Response Coordination Agent | Turns confirmed hazards into prioritized, sequenced response tasks |
| Public Advisory Agent | Drafts approval-gated crew/passenger advisories (never claims transmission) |
On startup it sends one demo incident through the pipeline and prints the assembled brief,
then stays running. Use --no-demo to skip the demo, or --once to exit after it. Each
agent's address is printed at startup. Leave this terminal running.
4. Start Redis (terminal 3, optional)
Only if you want Redis crisis memory persistence:
redis-server
Or point REDIS_URL in .env at a hosted Redis instance β no local Redis process needed.
5. Agentverse connectivity
The Bureau batch-registers all four agents on Agentverse automatically at startup
(Batch registration on Almanac API successful) β no manual connection step.
To run the agents as separate processes instead (each on its own port, e.g. for
individual Agentverse mailbox/proxy connection), use the single-agent runner β see
Agent-to-agent communication. Standalone agents honor
FETCH_CONNECTIVITY (proxy default, or mailbox/endpoint).
6. Verify
curl http://localhost:8000/
curl http://localhost:8000/api/fetch/status
Stop everything
for p in 3000 8000 8100; do lsof -ti:$p | xargs kill 2>/dev/null; done
Run scripts reference
| Command | What it does |
|---|---|
npm run dev | Frontend + API together (recommended) |
npm run dev:web | Next.js only on :3000 |
npm run dev:api | FastAPI only on :8000 |
npm run dev:agents | All four Fetch.ai uAgents in one Bureau on :8100 β Agentverse-discoverable + real agent-to-agent communication |
Run agents as separate processes instead of the Bureau (each binds its own port
8100β8103 and uses FETCH_CONNECTIVITY; note cross-process A2A needs Almanac/ledger
network access):
cd api && . .venv/bin/activate && python3.13 fetch_agents/run_agent.py orchestrator # :8100
cd api && . .venv/bin/activate && python3.13 fetch_agents/run_agent.py hazard # :8101
cd api && . .venv/bin/activate && python3.13 fetch_agents/run_agent.py response # :8102
cd api && . .venv/bin/activate && python3.13 fetch_agents/run_agent.py advisory # :8103
Agent-to-agent communication
The four agents collaborate via Fetch.ai uAgents messaging. The orchestrator runs a
pipeline: it dispatches the incident to the Hazard Intelligence Agent, threads that
assessment into the Response Coordination Agent, threads both into the Public Advisory
Agent, then synthesizes the bridge brief β each specialist builds on the previous one's
output. Messaging uses ctx.send_and_receive with an internal SpecialistQuery /
SpecialistReport model pair (api/fetch_agents/messages.py), kept separate from the
public chat protocol used for Agentverse discovery.
npm run dev:agents runs the whole fleet in one Bureau, which routes messages between
agents in-process and sends one demo incident through the pipeline on startup:
npm run dev:agents
# custom scenario / options:
cd api && . .venv/bin/activate && python fetch_agents/run_fleet.py "Bilge alarm on Deck 3; smoke in the Engine Room"
cd api && . .venv/bin/activate && python fetch_agents/run_fleet.py --once # exit after the demo brief
cd api && . .venv/bin/activate && python fetch_agents/run_fleet.py --no-demo # just run the discoverable fleet
You'll see the orchestrator dispatch to each specialist (with Received A2A query β¦ building on it) and print the assembled brief.
Why a Bureau? Cross-process uAgent messaging resolves peer addresses via the Fetch.ai Almanac (ledger network access). When that network is unavailable, a Bureau routes messages in-process so the agents still collaborate with no external dependency, while still batch-registering on Agentverse for discoverability. To run agents as separate processes, use
run_agent.py(above).
Run Frontend
npm run dev:web
Open http://localhost:3000/dashboard.
Run Backend
npm run dev:api
Backend health check: http://localhost:8000/.
Run Frontend and Backend Together
npm run dev
This installs frontend dependencies, creates/uses api/.venv, installs the FastAPI app, sources the root .env, starts the backend on http://localhost:8000, and starts the frontend on http://localhost:3000.
Redis is optional. With REDIS_URL=redis://localhost:6379, start a local Redis separately if you want persistence; otherwise the app falls back to memory.
Docker Compose
docker compose up --build
Start Simulation
curl -X POST http://localhost:8000/api/incidents -H 'Content-Type: application/json' -d '{}'
curl -X POST http://localhost:8000/api/incidents/<incident_id>/simulate/start
curl -X POST http://localhost:8000/api/incidents/<incident_id>/agents/run
Each simulation call advances one deterministic shipboard fire/flood event.
Fetch.ai and Redis Integration
Fetch.ai ASI:One and Redis are optional. The backend runs without either one.
Fetch.ai:
- Set
ASI_ONE_API_KEYandAGENTVERSE_API_KEYin local.env. - Agent messages, incident briefs, public alert drafts, and command parsing use ASI:One when available.
- See Quick Start above for startup and Agentverse mailbox steps.
- Check
GET /api/fetch/statusfor agent addresses and ASI:One configuration. - If ASI:One is missing or fails, deterministic fallback text is used.
Redis:
- Set
REDIS_URLtoredis://...orrediss://.... - The incident store writes
IncidentStateJSON to Redis underfloodfire:incident:{incident_id}. - The incident index is stored in
floodfire:incidents. - Crisis memory records are stored as Redis hashes under
floodfire:memory:{memory_id}. - Each incident has a memory set at
floodfire:incident:{incident_id}:memory_ids. - Each incident also writes operational events to a Redis Stream at
floodfire:incident:{incident_id}:stream. - Agents retrieve Redis memory before ASI:One generation and include recalled shipboard context in their prompts.
- The dashboard shows Redis memory status, memory count, stream support, vector-search readiness, and recalled records in the Redis Crisis Memory panel.
- If Redis is unavailable, the app continues with in-memory state.
Redis prize-track demo path:
- Start Redis locally or point
REDIS_URLat a hosted Redis instance. - Run
npm run dev. - Open
/dashboard. - Click
Run Scenario Stepseveral times. - Click
Analyze Incident. - In
Redis Crisis Memory, clickReindex, thenRecall. - Explain that Redis is being used for shipboard agent memory, context retrieval, stream event history, and optional vector-search capability detection, not just caching.
Secrets:
- Do not commit
.env. - Do not paste real keys into source files.
.env.examplecontains placeholders only.
Arize Observability
Arize AX gives the agent fleet LLM tracing plus an automated evaluator that scores agent output against the CrisisRoom safety policy.
Setup
-
In Arize, copy your Space ID and an API Key (Space Settings β API Keys).
-
Put them in
.env:ARIZE_API_KEY=... ARIZE_SPACE_ID=... ARIZE_PROJECT_NAME=floodfire-crisisroom # optional, this is the default -
Start the API (
npm run dev:api) and exercise the agents (create an incident, run agents, draft an alert). Every ASI:One call is auto-instrumented via OpenInference and streamed to Arize as a trace, wrapped in a per-agent span (e.g.Flood Analyst Agent,Incident Brief,Alert Draft) carryinginput.value,output.value, and agent/task metadata.
Confirm wiring at any time:
curl http://localhost:8000/api/observability/status # -> { "arize": { "enabled": true, ... } }
Evaluator
api/scripts/arize_eval.py is an LLM-as-judge that closes the loop. At trace time
each generation's span_id + I/O is buffered to api/.arize_eval_queue.jsonl; the
evaluator scores each one on two criteria and logs the results back onto the exact
Arize spans (visible as feedback on the trace):
safety_policyβ flags any output that claims a public alert was sent, recommends automatic dispatch, or omits uncertainty on unverified reports.groundednessβ checks the output is supported by the incident context.
cd api && . .venv/bin/activate
python scripts/arize_eval.py --dry-run # score locally, print results
python scripts/arize_eval.py # score and upload evals to Arize
python scripts/arize_eval.py --limit 50 # only the 50 most recent spans
This evaluator surfaced and let us tighten prompts that occasionally implied alerts
had already been transmitted β the safety_policy fail rate is how we measure that
improvement in Arize.
API Endpoints
GET /: health checkPOST /api/incidents: create simulated incidentGET /api/incidents: list incidentsGET /api/incidents/{incident_id}: full incident statePOST /api/incidents/{incident_id}/simulate/start: advance simulationPOST /api/incidents/{incident_id}/reports: add field reportGET /api/incidents/{incident_id}/reports: list reportsPOST /api/incidents/{incident_id}/agents/run: run scaffold agentsGET /api/incidents/{incident_id}/agents/messages: list agent messagesGET /api/incidents/{incident_id}/tasks: list tasksPATCH /api/tasks/{task_id}: update task statusPOST /api/incidents/{incident_id}/briefing: generate situation reportPOST /api/incidents/{incident_id}/public-alert-draft: generate public alert draftPOST /api/voice/transcribe: Deepgram placeholder transcriptionGET /api/incidents/{incident_id}/memory/capabilities: Redis memory and vector-search statusGET /api/incidents/{incident_id}/memory/search?q=...: retrieve relevant Redis crisis memoriesPOST /api/incidents/{incident_id}/memory/reindex: rebuild Redis memory from current incident stateGET /api/fetch/status: Fetch.ai ASI:One and uAgent registry statusGET /ws/incidents/{incident_id}: WebSocket incident updates
Sponsor Integration Checklist
Core:
- Anthropic for agent reasoning and incident briefs
- Redis for incident memory, vector search, semantic deduplication, and agent state
- Deepgram for voice field reports and spoken briefings
- Band for multi-agent shared rooms
- Fetch.ai for discoverable emergency agents
- Browserbase for web-using official-source checks
- Arize for LLM tracing and output evaluation
- Sentry for frontend/backend error monitoring
Known Limitations
- Map is a Leaflet/Mapbox-style placeholder, not a real tile map.
- External data connectors return mock or empty data until credentials and API clients are added.
- Agent outputs use ASI:One when configured; otherwise deterministic fallbacks are used.
- Redis is optional; the default store is in-memory and resets on restart.
- Public alerts cannot be sent from this app.
Next Steps
- Expand Fetch.ai uAgent orchestration and Agentverse discoverability.
- Add Redis-backed persistence in
api/app/services/redis_store.py. - Replace
HazardMap.tsxwith Leaflet or Mapbox. - Wire Deepgram audio upload in
api/app/connectors/deepgram_client.pyandVoiceReportPanel.tsx. - Add production auth, audit logging, and human approval workflow before any real deployment.
Analysis
View
Metric
- 32
- 9
- 7
- 1
Figures cover GitHub contributors during the hackathon window. A co-authored commit counts in full for each author, so per-member totals add up to more than the whole-team figures.
Technology
- CSSIn code
- FastAPIIn code
- HTMLIn code
- JavaScriptIn code
- Next.jsIn code
- OpenAIIn code
- PythonIn code
- ReactIn code
- RedisIn code
- Tailwind CSSIn code
- TypeScriptIn code
- AnthropicClaimed
- DockerClaimed
11 of 13 appear in the indexed code. 2 claimed on Devpost could not be matched to code, which may simply mean the tool leaves no trace in the repository.
AI coding agents
- Claude CodeCommits
- CursorCommits
Detected from committed agent config files and commit authorship. Absence of a signal is not proof an agent was unused.
Codebase size
Source size
1.0 MB
Source files
138
Counts recognized source files only; vendored directories, binaries and lockfiles are excluded, so this is smaller than the repository on disk.
Repository
uc-berkeley-ai-hackathon-2026/crisis-room
162 files Β· 8.8 MB Β· @ d0e689b
Structure
Interface
23 files Β· 14%Screens, components and styles rendered to the user.
API & routing
75 files Β· 46%Request entry points: routes, handlers and controllers.
Application logic
9 files Β· 6%Domain rules, services and shared utilities.
Background jobs
1 file Β· 1%Work run outside a request: tasks, workers and schedules.
Supporting
Layers are inferred from where files sit in the tree, not from reading the code. A project that names its directories unconventionally will read oddly here β open the file browser to check anything the diagram implies.
Languages
- HTML55%
- Python27%
- Markdown10%
- TypeScript8%
- JavaScript0%
- YAML0%
- Other (1)0%
Share of indexed source by file size. Binary and vendored files are excluded.
Dependencies
api/pyproject.toml
pypi Β· 25- arize
- arize-otel
- fastapi
- httpx
- numpy
- openai
- openinference-instrumentation-openai
- pandas
- pydantic
- pydantic-settings
- python-dotenv
- python-multipart
- redis
- redis-agent-memory
- redisvl
- sentence-transformers
- sentry-sdk[fastapi]
- uagents
- +7 more
apps/web/package.json
npm Β· 13- @sentry/nextjs
- @types/node
- @types/react
- @types/react-dom
- next
- react
- react-dom
- typescript
- +5 more
package.json
npm Β· 11 development-only dependencies.
Declared in the repositoryβs manifests at the indexed commit. A declared package is not proof it is used, and runtime dependencies are listed first.
This projectβs features have not been analysed yet.
Export this project's context (description, README, evidence, key source files) to chat with an AI agent elsewhere.