The whole thing in one breath
Open data goes in: buildings, tree heights, ground height, schools and weather. A scene builder cuts a 1 m grid around each school. SOLWEIG, a radiation model, works out how hot every square metre feels for every hour of the school day. A model of a child's body turns that into a core temperature and the water lost. A fast model in your browser predicts what trees would change, and SOLWEIG checks it. An agent writes plans with tools that can't lie about numbers. Everything ends up as plain files that the website reads.
- ingest Overture, Meta canopy, Copernicus, OpenStreetMap, ERA5
- scene a 1 m grid per school: ground, roofs, crowns, what counts as yard
- solweig mean radiant temperature, then UTCI, hour by hour
- twin the child's morning, and the files the planner needs
- publish ranking, maps and twins into
web/ - web the site, the planner and its instant preview
- api + worker "Verify with physics": a real SOLWEIG run on your design
Physics, from the ground up
A thermometer in the shade reads the air. A child in an open yard is not in the shade. They take in direct sun, the glare of the sky, sunlight bouncing off the ground, and heat glowing off every surface that has been baking since morning. Add all of that up and you get the mean radiant temperature: the temperature of an imaginary room that would bathe you in the same radiation. In a Delhi yard at 1 pm it runs 20 to 25 °C above the air.
SOLWEIG computes it for a person standing on every cell of the grid. It casts shadows from roofs and crowns (crowns let a little light through), measures how much sky each cell can see, and sums the short- and long-wave radiation arriving from six directions. ThenUTCI folds in air temperature, humidity and wind to give one "feels like" number on a scale built around the human body. Above 46 °C is extreme heat stress. We run UMEP's Rust implementation on a laptop GPU: about four seconds for a 250 m school.
Making it instant
Four seconds is fast for physics and slow for a mouse. The trick is to predict thechange, not the temperature. Squares your design doesn't touch keep SOLWEIG's exact value. Where you plant, the browser recasts shadows from the new crowns and applies a small model of how much a square cools when it goes from sun to shade, fitted per hour to SOLWEIG runs of that same school. It takes about 10 ms.
Then we check it. Tests set the browser's shadow caster against SOLWEIG (they agree on more than 97% of cells) and the preview against full runs of designs it never saw (under 1 °C off on average). Right under a new crown the preview can be a few degrees off at midday, and the page tells you so. "Verify with physics" sends your design to a worker that reruns SOLWEIG and the child's day.
A child, not an average
JOS-3 models a body as 17 segments, each with core, muscle, fat and skin, and simulates sweating and blood flow minute by minute. We scale it to a nine-year-old (1.32 m, 28 kg) and walk it through a government school's morning shift: assembly outdoors, class, recess, the walk home. Outdoors it stands in the yard's typical radiant heat for that hour.
JOS-3 was built from adults, so its set points don't scale down to children. Neem reports what holds up: the rise above the child's own resting state, and the water lost. Treat them as indicative, not clinical.
An agent that can't make numbers up
The planner is a Strands agent running qwen3 4B through Ollama, on the same laptop. It gets a school, a budget and five tools: read the brief, plant trees, add a shade sail, preview, verify. The model decides how many trees, which species and whether a sail is worth it. The tools decide where (the hottest open ground, a crown's width apart), refuse to overspend, and compute every number. If the model forgets to verify, the code does it anyway.
The rule is simple: a language model may choose, but only physics may report. That is what makes it safe to put its plans in front of a principal.
The cloud, on a laptop
infra/template.yaml is an AWS SAM template for the whole service: an API on Lambda, a worker on SQS, a Step Functions map that ranks schools on up to a hundred workers at once, DynamoDB for jobs and S3 for the data lake. LocalStack emulates all of it, sosam local runs the same Lambda images on your machine. Cedar holds the rules: anyone may explore, physics runs have a size and rate budget, and only a school's own planner may approve its plan, never one physics hasn't verified. Every AWS call goes through an adapter that takes an endpoint, so pointing it at real AWS is a config change.
Run it
You need uv, just and bun, on Windows, macOS or Linux:
git clone https://github.com/riteshroshann/neem
cd neem
uv sync && just check # Python: lint, types, tests
cd web && bun install && bun run dev # the site on :4321
uv run neem-api # the physics API on :8000The data pipeline rebuilds everything from public sources: just ingest,just scene <id>, just rank, just publish. The serverless stack: just localstack, just seed,just sam-build, just sam-worker. The planner, with Ollama running: just plan osm-w1321574340.
packages/neem-corephysics: scenes, trees and sails, SOLWEIG, the fast preview, the childpackages/neem-dataingest, the scene builder, the city ranking, publishingpackages/neem-agentthe Strands planner and its toolspackages/neem-api,neem-workerthe service, its queue and its Cedar rulesweb/this site: Astro with React for the planner and three.js for 3Drecon/phone video to a 3D model and measured heightsinfra/Docker, LocalStack and the SAM template
Files and API
The site needs no server. neem-data publish writes everything it shows as plain files, and each school with a twin gets a folder under /twins/<id>/:
twin.jsonthe school, its grid, and the yard's heat summary for every hourlayers.bin.gzthe grids, packed: ground height, roofs, crowns, what counts as yard, and radiant temperature and feels-like for every hourcalibration.jsonthe small per-hour model the instant preview runs onchild.jsonthe nine-year-old's morning, minute by minuteplan.jsonthe agent's plan, its steps and SOLWEIG's verdictmap-1pm*.pngthe 1 pm heat maps: today, with the plan, and at each modelled age
The physics API, uv run neem-api, serves the same data and runs the verification jobs. Cedar checks every call.
GET /schools,GET /schools/{id}the ranking and one schoolGET /schools/{id}/layers.bin,/calibration,/childa twin's filesPOST /schools/{id}/designstrees and sails in, a job id out (202)GET /jobs/{id}the job: queued, running, then SOLWEIG's numbersPOST /schools/{id}/approve,GET /schools/{id}/approveda school's own planner signs off a verified planGET /health,GET /whoamiliveness, and who Cedar thinks you are
Worlds you can walk through
Neem's 3D today is honest but blocky: one column per square metre, from open data. A real yard has a water tank, a stage for assembly, a wall with a crack in it and the exact lean of every tree. Two ideas from computer vision close that gap, and they fit together.
Gaussian splats. A splat scene is a cloud of millions of tiny, soft, coloured blobs. Each blob is only a few numbers: where it sits, how it is stretched and turned, its colour, and how see-through it is. To draw a frame you sort the blobs by distance and paint them back to front. To build a scene you start from a rough point cloud and nudge every number by gradient descent until the renders match the photos. No meshes and no textures, just blobs that end up looking exactly like the place.
The plan for recon/. Walk the empty yard with a phone for 60 to 90 seconds. VGGT, a 3D vision model, turns the frames into camera positions and a dense point cloud in one pass. The cloud is levelled, scaled against the mapped buildings and becomes measured heights for SOLWEIG. The same footage then trains a splat, and SOLWEIG's map is painted onto its ground: you walk through your own school and see where the sun will hurt at 1 pm.
World Labs is taking this furthest. Their world model,Marble, generates a persistent 3D world from a single image, a text prompt, a video or a rough 3D layout, and exports it as Gaussian splats and meshes. Their renderer,Spark, is open source under MIT and draws splats inside three.js, the engine Neem's 3D already runs on, on WebGL2 phones and headsets; Spark 2.0 is built to stream worlds of over 100 million splats into a browser.
Neem would use both, kept strictly apart. Measured: a splat of the real yard from a phone video, drawn with Spark, every number on it still from physics. Imagined: a generated world of the grown grove, seeded from a photo of the yard today, so a principal can stand under year thirty before planting year one, labelled as a picture and never as a result. Neither is built yet; the phone-to-heights pipeline is.
Extend it
Another city. Every source is global: Overture, the Meta canopy map, Copernicus, OpenStreetMap and ERA5. Change the boundary and the day, and the same commands build its schools. Another tree. A species is a height, a crown and how much light the crown lets through, set once in Python and once in the browser. Another question. SOLWEIG already computes shadow hours and radiant temperature for every cell; a new map is a publish step away. Better heights. Open data knows the height of about 0.5% of Delhi's buildings; recon/ turns a 60 to 90 second phone video into measured heights on the same grid.
The house rules: every number shown has to come from a run you can repeat, physics code keeps its textbook symbols, and a change that weakens a test is a bug.
How far this can go
The city ranking ran all 766 Delhi yards in about ten minutes, and a full 1 m twin takes about four seconds a school on one laptop GPU. The Step Functions map in the SAM template fans the same job out over a hundred workers, so a state, or a country with about 15 lakh schools, is a matter of compute, not of new code.
Next comes a phone in every yard: a short video becomes a 3D model, measured heights and a Gaussian splat you can walk through. Then the same twin every summer, with fresh canopy data, to check which saplings made it and what they are doing for the children under them. Then the ground beyond schools: bus stops, hospital courtyards, streets and parks. One engine, any open ground where people wait in the sun.
For NGOs, CSR teams and foundations
If you plant trees or work with schools, Neem can do the parts that are hard to do by eye.Where: rank a district's schools by how hot their yards get for the children in them.What: a plan inside your budget, with a verified cooling number, before a single sapling goes in. A neem costs about ₹3,500; 85 of them, ₹2,97,500, are what the planner chose for Kendriya Vidyalaya. Proof: the same physics after planting and year by year as the trees grow, numbers you can put in a donor report and defend. Open: the code is GPL and the data is public, so there is nothing to lock you in.
A simple way to start: pick a district, we run the ranking and the twins, you plant with the schools that need it most, and we re-run every summer. Every yard that becomes a grove is a classroom for the children who will plant the next one.