Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

92 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

INN-SIGHT

The AI consultant that tells you what to build, before you build it.

Place a hotel, homestay, or B&B on a real Toronto map, toggle concrete vs mass timber and central HVAC vs heat pumps, stress-test the design against a fully booked heat-wave weekend, and receive an investor-style memo: construction cost, annual energy cost, tCO2e per year with sources, a documented community-friction heuristic, and a recommendation with reasoning. A Rules & Compliance Engine then lays your massing beside Toronto zoning / OBC / TGS clauses so you can see what you are actually allowed to build here — not just what you should.

Built at Hack the 6ix 2026.

Live: app (API on Render free tier cold-starts ~50 s on first request)

Stack

  • web/ Next.js (App Router, TypeScript, Tailwind), MapLibre GL satellite assembler with a Three.js modular massing layer
  • api/ FastAPI (Python 3.11+)
  • model/ benchmark library and deterministic stress-test engine, pytest-covered

Architecture

A three-package monorepo with a hard line between a deterministic simulation core and everything that touches the network, so the numbers in the memo never depend on a live service being up.

  • model/ is a pure, dependency-light Python library. Every benchmark constant is a sourced record, and the stress test is a set of pure functions (no randomness, no wall clock) mapping (BuildingConfig, StressScenario) to an OptionResult. That is what makes results byte-for-byte reproducible, and it lets a pytest lock the homestay-to-hotel recommendation flip.
  • api/ is a FastAPI service that wraps the model, orchestrates the multi-agent briefing (six specialists in parallel, then a boss synthesis), runs the five-scenario year-pack stress in parallel under a hard time budget, and fronts every live data source behind a deterministic or benchmark fallback.
  • web/ is a Next.js client (App Router, TypeScript). A MapLibre GL satellite assembler with a custom WebGL layer renders a parametric Three.js building in true geographic metre-space on the real parcel polygon. It holds the UI state and is a thin front end over the API.

Cross-cutting: every integration (Auth0, Stay22, Gemini, ElevenLabs, Electricity Maps, Backboard) sits behind a feature flag, so the core loop runs with no keys at all; identical runs are fingerprint-cached in MongoDB so Gemini is not re-billed; and Auth0 does server-side RS256 JWT verification, not just a UI gate.

flowchart LR
  subgraph web["web/ (Next.js, MapLibre, Three.js)"]
    UI["Assembler, A/B toggle, memo"]
    Voice["ElevenLabs voice agent"]
  end
  subgraph api["api/ (FastAPI)"]
    Routes["Routes: compare, memo, briefing, sites, area"]
    Agents["Multi-agent orchestrator (6 specialists + boss)"]
  end
  subgraph model["model/ (deterministic engine)"]
    Sim["Stress-test simulation"]
    Bench["52 sourced benchmarks"]
  end
  UI --> Routes
  Voice --> Routes
  Routes --> Sim
  Routes --> Agents
  Agents --> Sim
  Sim --> Bench
  Agents -->|structured JSON| Gemini[("Google Gemini")]
  Routes --> Mongo[("MongoDB Atlas")]
  Routes --> Auth0["Auth0"]
  Routes --> Live["OSM Overpass, Open-Meteo ERA5, Electricity Maps, Stay22"]
Loading

Run it

# api (from repo root)
python3.11 -m venv .venv && .venv/bin/pip install -r api/requirements.txt
.venv/bin/uvicorn main:app --app-dir api --port 8000

# web
cd web && npm install && npm run dev

Put secrets in a single repo-root .env (never commit it); FastAPI and the Next.js server read it directly. One exception: the Next.js middleware (which mounts the /auth/* routes) can only read env files inside web/, so after editing the root .env run python3 scripts/sync-web-env.py to mirror the auth keys into a gitignored web/.env.local. If /auth/login returns 404, that mirror is missing or empty. Every integration is feature-flagged; the core loop runs with no keys at all.

Auth0 example keys in that same file:

NEXT_PUBLIC_FLAG_AUTH0=true
AUTH0_DOMAIN=...
AUTH0_CLIENT_ID=...
AUTH0_CLIENT_SECRET=...
AUTH0_SECRET=...
APP_BASE_URL=http://localhost:3000

Demo

Demo

What the capture shows, in order: enter from the landing page, land on the default site (45 The Esplanade on the City of Toronto's 8 cm aerial imagery, with neighbouring buildings extruded at their real OSM heights and live site climate from Open-Meteo), pick from real empty parcels found live on OpenStreetMap (surface parking, brownfield, construction; each cleared against building footprints by polygon intersection), assemble the building component by component (foundation, structure, floors, facade, energy systems) while the physics and structure log narrates each choice, toggle Option A (concrete + central HVAC) against Option B (mass timber + heat pumps), run the year stress (five named extreme weekends in parallel, including the documented 36.2 C July 14, 2026 Toronto heat event), and read the portfolio memo.

The honest numbers under it: for the 40-room boutique, the flip to Option B costs $159 per tonne of CO2e avoided over the RICS 60-year life, under Canada's $170 federal 2030 benchmark; for a 6-room homestay the same swap fails the bar at $358 per tonne and the memo recommends Option A. That flip is enforced by a pytest.

Real vs Simulated ledger

Honesty first: this table says exactly what is real and what is a labelled simulation. Updated every phase.

Piece Status
Benchmark constants (52: energy intensity, rates, carbon factors, costs) Real published values (CBECS 2018 tables, Toronto Hydro and Enbridge 2026 rate schedules, TAF emissions guidance, Altus 2025 cost guide, RICS WLCA); every constant in model/innsight_model/benchmarks.py carries a source URL or an ESTIMATE flag with its derivation
Stress-test engine Real deterministic model on those constants; 25 pytest including determinism and the homestay/hotel recommendation flip
Empty-parcel finder Live OSM Overpass (surface parking, brownfield, construction, vacant) with real polygon building-exclusion; fallbacks: session cache, then parcels traced from the 2025 orthophoto, then labelled approximate pads; green plots, price pins, and context buildings refresh live as you search or pan anywhere on the map
3D context buildings Neighbouring OSM footprints extruded at tagged heights (height / building:levels); follow the active site and the panned viewport with stale-fetch guards; decorative, hidden when data is unavailable
Hourly load curves Generated from published load-profile behaviour; in-app validation overlay against a metered hotel study (Placet et al. 2010)
Stay22 market pulse Real live API calls at the selected parcel lat/lng (authenticated tier when keyed), forward dates, no listing storage; competitor rate pins on the map, six-Saturday peak-weekend calendar scan, revenue line; cache fallback disclosed in-UI; unit-tested against fixture payloads
Electricity Maps carbon Live zone intensity when ELECTRICITYMAPS_API_KEY is set (lat/lon then CA-ON fallback); else TAF Ontario benchmarks
Open-Meteo climate curves Archive hourly temps at the pin → five named extreme 48h weekends for year-pack sim; Toronto fixed curves if unreachable; not 8760h
Multi-agent briefing Specialists (market, environment, neighbourhood, green ratio, friction, compliance) + boss; Gemini structured JSON when keyed, deterministic stubs otherwise; sim remains source of truth for A/B numbers
Rules & Compliance Engine Side-by-side massing vs City of Toronto / Ontario pack (height, setbacks, angular plane, FSI, parking, OBC/EMTC, TGS); shows model next to clause + delta — not a pass/fail permit gate; overlays are labelled heuristics, not parcel-matched legal surveys
Agent inference footprint Token usage from Gemini usage_metadata when live; energy/gCO2e are labelled estimates (~0.3 Wh/1k tokens × live Electricity Maps or TAF Ontario gCO2e/kWh); shown on year-pack memo + physics log
Year-pack parallel stress One action runs all five extreme weekends in parallel (deterministic sim matrix, location climate when live); shared Stay22/env gather; ~8 Gemini calls total (6 specialists + year boss + one portfolio memo), not 5× full briefing; live pulls run under a 9 s hard budget and the ERA5 archive under 8 s, and if the full run cannot finish in 50 s the client reruns in a deterministic fast mode (same memo shape, labelled generator), so the stress button can never hang
Seasonal stress scenarios Named extreme weekends (heat-wave, summer shoulder, typical July, typical winter, deep cold); 48h peak curves with heating + cooling; annual energy still CBECS averages, not 8760h weather
Per-user past runs Mongo memo_runs metadata + reopenable report blob (year memo, multi-agent briefs, scenario matrix) when Auth0 signed in; click Past runs to restore; no Stay22 listings; JWT verification still a follow-up
Fingerprint run cache Exact fingerprint on site (lat/lng to 4 dp) + building A/B + storeys/shape + kind; /briefing and /briefing/year reuse prior report (skip Gemini) when matched; force_refresh bypasses; labelled from_cache in API + physics log
Memo narrative Gemini structured output over real computed numbers (single-scenario or year portfolio); deterministic fallback without a key, generator labelled in-UI
Streetscape renders Illustrative AI imagery via Nano Banana; live prompts include storeys, plan shape, structure, facade, HVAC, and site name; static A/B fallbacks disclosed when unmatched
Community friction score Documented heuristic (model/friction.md), not survey data
Building geometry Illustrative massing (rooms × storeys × shape); MapLibre rings + Pixi levels track storeys/shape; not permit-ready drawings
Plan-shape modifiers Labelled estimates (slab / l_wing / courtyard / podium_tower facade, circulation, embodied factors); GFA still rooms × SQFT_PER_ROOM; room-per-storey distribution is derived, not surveyed
Grid strain class Published factors as a proxy, not utility telemetry
Pixel viewport Visualization driven by real sim outputs, decorative art style
In-app chatbot Gemini-backed reasoning over the app's own computed context; deterministic fallback without a key, generator labelled
3D massing Modular Three.js massing driven by rooms x storeys x plan shape; illustrative, not permit-ready
Stakeholder memory Backboard.io memory per signed-in user and role, recalled into chat grounding and written back after answers; strictly additive, chat unchanged without a key
Compliance panel Deterministic rules engine vs a curated Toronto pack (height, angular plane, setbacks, FSI, EMTC, parking); every limit labelled heuristic or estimate, GFA shared with the sim, not legal advice

Licences and data credits

Map imagery: City of Toronto 2025 orthophoto (contains information licensed under the Open Government Licence - Toronto) over Esri World Imagery (attribution in-app). Benchmarks: US EIA CBECS, EC3/Building Transparency, OEB, ECCC, IESO (URLs inline in code and memo footnotes).

About

(Winner) Place a hotel, homestay, or B&B on a real Toronto map, stress-test it against a fully booked heat-wave weekend, and get an investor-grade memo: cost, carbon, grid strain, and community friction, every number sourced. Hack the 6ix 2026.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages