Adds an additive emissions ledger that records every llm.chat call
and every remote app.inference._post call, surfacing the per-query
total Wh / J + token counts on the briefing.
Backend
- app/emissions.py: thread-local Tracker with hardware power profiles
(MI300X 600 W, T4 50 W, Apple M 20 W, x86 30 W) and a summarize()
rollup with by-kind, by-hardware, and frontier-cloud comparison.
- app/llm.py: chat() times each call, picks hardware via engine
detection, reads prompt/completion tokens from LiteLLM usage for
non-stream calls, estimates from response text for streams.
- app/inference.py: _post() records duration vs the MI300X profile.
- app/fsm.py: captures the parent-thread tracker and re-installs it on
the iter_steps runner thread (mirrors the token_callback pattern);
attaches `emissions` alongside the existing `energy` block in both
run() and the iter_steps final event.
- app/context/eo_chip_cache.py + app/flood_layers/prithvi_live.py:
ThreadPoolExecutor initializ…
feat: every EO specialist's prediction renders as a map layer
Round-tripped the per-pixel argmax raster from the droplet so the HF
Space can vectorise it onto WGS84 polygons and the MapLibre layer
actually paints the live model output. Was: only terramind_synthesis's
local fallback path generated polygons; everything else returned
class fractions only and the map showed nothing.
Wire format: droplet's /v1/prithvi-pluvial and /v1/terramind responses
gain `pred_b64` (uint8 base64) + `pred_shape` + (terramind only)
`class_labels`. Small payload — 224x224 uint8 round-trips in ~50 KB.
HF side:
- new app/context/_polygonize.py: polygonize_class_raster() and
polygonize_binary_mask() helpers
- app/context/eo_chip_cache.py adds `bounds_4326` to chip output
- app/context/terramind_nyc lulc/buildings accept bounds_4326,
_try_remote polygonises the response and attaches polygons_geojson
- app/context/terramind_synthesis.py polygonises the remote response
- app/flood_layers/prithvi_live.py polygonises the remote water mask
- app/fsm.py threads chip.boun…
Squashed from 5438cc8..6904684. The slides/asce/deck.pptx is tracked
via git-lfs (added *.pptx to .gitattributes), so this commit carries
only the LFS pointer — no binary blob in history.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Stones C4: wire TerraMind-NYC LULC + Buildings into FSM
Adds three new Burr actions in app/fsm.py (gated behind
RIPRAP_HEAVY_SPECIALISTS):
step_eo_chip -> writes eo_chip (S2L2A + S1RTC + DEM)
step_terramind_lulc -> writes terramind_lulc
step_terramind_buildings-> writes terramind_buildings
eo_chip is a per-query cache: one ~150 MB Sentinel-2/1/DEM fetch from
Microsoft Planetary Computer, shared by both TerraMind specialists so
they don't each refetch. The cache lives in app/context/eo_chip_cache.py
and gracefully no-ops when terratorch / planetary_computer / pystac_client
/ rioxarray aren't installed.
Both TerraMind specialists call into app/context/terramind_nyc.py (added
in C3), which routes inference through terratorch tiled_inference at
224x224 and ships the per-class fraction summary the reconciler quotes.
Reconciler:
- app/reconcile.py:build_documents() now emits tm_lulc (Touchstone,
after prithvi_live) and tm_buildings (Keystone, after the legacy
terramind_synthetic prior).
- trim_docs_to_pl…