π Winner β Hack Canada 2026
Transit Planner is an AI-powered urban transit planning tool that simulates a city council deliberation to design, debate, and approve new transit routes. Built for Toronto, it combines multi-agent AI, real-time geospatial visualization, and voice narration to make transit planning accessible, transparent, and engaging.
A structured 6-round deliberation where specialized AI agents debate a proposed transit route β each with distinct values, priorities, and personalities:
| Agent | Role | Model |
|---|---|---|
| Alex Chen | Ridership Planner β proposes routes for equity and underserved areas | Claude Sonnet |
| Jordan Park | Infrastructure Analyst β critiques costs, ROI, and feasibility | Claude Sonnet |
| Margaret Thompson | NIMBY Resident β raises neighborhood disruption concerns | Claude Haiku |
| Devon Walsh | PR Director β flags gentrification and displacement risks | Claude Haiku |
| Alex & Jordan | Joint Rebuttal β defend or revise the proposal | Claude Sonnet |
| Planning Commission | Final Decision β issues a binding verdict with mitigations | Claude Sonnet |
Each round streams in real-time. Routes update live on the map as agents propose alternatives.
- Draw custom routes or boundaries directly on the map
- Select neighborhoods and existing TTC stations as context
- See population density, traffic levels, and employment overlays
- View generated routes rendered in real-time as the council deliberates
Animated Three.js globe with orbiting transit lines and trains, giving the app a cinematic entry point.
ElevenLabs text-to-speech narrates key quotes from each agent, with distinct voice IDs per character.
All council sessions are persisted and replayable β review past deliberations and route outcomes.
Frontend
- Next.js 15 (App Router, React 19)
- TypeScript
- Mapbox GL + MapboxDraw β interactive map and route drawing
- Three.js + React Three Fiber β 3D globe visualization
- Tailwind CSS 4
- tRPC + React Query β type-safe API layer
Backend
- FastAPI (Python) β core AI orchestration engine
- Backboard.io β LLM API wrapper with thread-based conversations
- Anthropic Claude (Haiku 4.5 + Sonnet 4.5)
- ElevenLabs β text-to-speech per agent voice
- PostgreSQL + PostGIS β geospatial transit data
- Supabase β hosted database
- Go β routing management API
Infrastructure
- Monorepo with npm workspaces
- Docker
- GitHub Actions (CI/CD)
transit-planner/
βββ web/ # Next.js frontend β βββ src/app/ β βββ page.tsx # Landing page (3D globe) β βββ map/page.tsx # Main planning interface β βββ api/ β βββ council/ # Proxies to Python AI backend (SSE) β βββ tts/ # ElevenLabs text-to-speech β βββ traffic/ # Traffic data β βββ population/ # Population density data β βββ python_server/ # FastAPI β AI council engine β βββ api/ β βββ council.py # 6-round multi-agent orchestration
β βββ backboard.py # LLM API wrapper (Claude via Backboard.io)
β βββ data_tools.py # PostGIS queries, neighborhood GeoJSON
β βββ go_server/ # Routing management API
βββ express_server/ # Express backend (optional services)
βββ web_db/ # Prisma schema
βββ python_utils/ # Shared DB models (SQLAlchemy + PostGIS)
Data flow:
- User selects neighborhoods/stations and submits a planning request
- Next.js
/api/councilproxies the request to the Python FastAPI backend - Python fetches relevant transit data from PostgreSQL/PostGIS
- The council orchestrator opens 6 sequential LLM threads via Backboard.io
- Each agent streams their response back via Server-Sent Events
- Frontend parses SSE events, updates the chat panel and map in real-time
- Final approved route is rendered on the Mapbox map
# Install all dependencies (root + web workspace)
npm install
# Install Python dependencies
cd python_server && pip install -r requirements.txt
# Copy and fill in environment variables
cp .env.example .envFrontend:
cd web && npm run devPython backend:
./python_server/run.shOr directly:
.venv/bin/uvicorn python_server.api.main:app --host 0.0.0.0 --port 8000 --reload --reload-dir python_server --reload-dir python_utilsRequires: Node.js 20+, Python 3.11+, PostgreSQL with PostGIS.
web/.env.local (Next.js frontend)
| Variable | Description |
|---|---|
NEXT_PUBLIC_MAPBOX_TOKEN |
Mapbox GL public token β map rendering |
BACKBOARD_API_KEY |
Backboard.io API key β proxies Claude requests |
ELEVENLABS_KEY |
ElevenLabs API key β agent voice narration |
SUPABASE_URL |
Supabase project URL |
SUPABASE_KEY |
Supabase anon/service key |
PYTHON_SERVER_URL |
URL of the FastAPI backend (default: http://localhost:8000) |
GOOGLE_MAPS_API_KEY |
Google Maps API key β Street View panel |
AUTH0_SECRET |
Long random string for session encryption |
AUTH0_BASE_URL |
App base URL (e.g. http://localhost:3000) |
AUTH0_ISSUER_BASE_URL |
Auth0 domain (e.g. https://your-tenant.auth0.com) |
AUTH0_CLIENT_ID |
Auth0 application client ID |
AUTH0_CLIENT_SECRET |
Auth0 application client secret |
python_server/.env (FastAPI backend)
| Variable | Description |
|---|---|
ANTHROPIC_API_KEY |
Anthropic API key β used if not routing via Backboard |
BACKBOARD_KEY |
Backboard.io key β Claude via Backboard |
SUPABASE_DB_URL |
PostgreSQL connection string with PostGIS |
Built At Hack Canada 2026 β Top 10 Google - Build with AI Track
MIT