Adds a local-inference path (FlutIQ Edge via Ollama / Gemma 4 e4b)
alongside the existing cloud path (FlutIQ Cloud via OpenRouter / Gemma
4 31B). Same FastAPI server, same agents, same frontend; INFERENCE_BACKEND
env var picks the LLM endpoint. Verified end-to-end on an M4 Pro 24 GB:
/api/assess for a Chicago address completes in ~190s with all 9 agents
finishing on gemma4:e4b. Frontend re-skins itself based on data-variant
so judges can tell the modes apart at a glance (blue Cloud / green Edge).
Directly addresses the hackathon brief's "local frontier intelligence"
and "privacy is non-negotiable" framing.
Reframes the dossier as an expert briefing for someone about to live,
buy, or rent at the property — value is synthesis and time, not novel
prediction:
- risk_agent gains a plain_verdict field (3-5 sentences, second-person,
~10th-grade reading: bottom line first, then most important reason,
then trend direction)
- advisor_agent gains before_you_move_in[] (3-5 due-dilige…
Adds a language dropdown in the chrome bar that controls the language
of all user-facing copy in the dossier. Hits the Digital Equity &
Inclusivity track, and is the strongest single demo moment for the
mission framing — a Pilsen homeowner getting their flood-risk briefing
in Spanish without having to translate jargon.
Backend:
- New backend/app/data/languages.py — registry of 7 supported codes
(en, es, zh, vi, ht, ar, tl) covering ~80% of non-English-speaking
households in US flood-prone metros (USCB ACS 2022). normalize()
collapses 'es-MX' → 'es' and unknown codes → 'en'.
- prompt_directive(code) emits the language directive injected into
the risk + advisor agent system prompts. Critical bilingual rule:
user-facing copy translates, but legal product names (NFIP flood
insurance, sewer/water-backup endorsement), URLs, phone numbers,
dollar amounts, and JSON keys stay English. Otherwise the homeowner
can't search/say the right thing to actually buy the product.
- Assess…
Stands up the FastAPI backend with one agent fully wired through the
SSE pipe so the architecture is proven before we fan out the rest:
POST /api/assess → geocode → FEMA NFHL → Gemma 4 interpret
→ agent_update events → complete{dossier}
Verified end-to-end against two cases:
- Houston Allen Pkwy (Zone AE) → is_sfha=true, requires_insurance=true
- Chicago S Drexel (Zone X) → gap_warning generated unprompted,
surfacing the urban-sewer-backup blind spot that is the whole pitch
Smoke-tested Gemma 4 on OpenRouter free tier (scripts/smoke_test.py):
basic completion, reasoning mode, and OpenAI-format tool calls all
pass on google/gemma-4-31b-it:free.
Spec bugs fixed while building:
- llm/client.extract_reasoning read message.reasoning_details[i].content;
the actual key is .text. Also falls back to top-level .reasoning string.
- tools/fema requested VERSION_ID, which does not exist on NFHL layer 28.
ArcGIS returned HTTP 200 with an {"error": ...} b…