DEV Community

Sneha Choudhary
Sneha Choudhary

Posted on

Tomorrow's Tray

Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady Submission 🦥

This is a submission for the Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady

What I Built

Every night, a baker closes the shop and guesses: how many croissants tomorrow?

Guess too low and the 11am customers find an empty tray. Guess too high and
the leftovers go in the bin. Most small bakeries do this from gut feeling.

Tomorrow's Tray takes the sales export from your till (a plain CSV) and
produces tomorrow's prep list: how many of each item to bake, with a range
instead of a single number, plus a one-line reason for each. The baker can
override any number. The tool suggests, the baker decides.

The part I care most about: a till counts sales, not demand. If the
croissants sold out at 10:40, the data says "36 sold", but real demand was
higher. Forecasting from that number quietly teaches your model to
under-bake. Tomorrow’s Tray treats sold-out days as censored observations: it estimates the demand that was missed as a range, using a Tobit-style conditional expectation blended with a diurnal arrival-curve correction, and never reports it below what actually sold.

The lazy part: the baker stops doing the nightly guessing and mental maths.

Demo

Live app: https://week-3-1-6qet.onrender.com/

The first load can take 30-60 seconds because the free instance wakes up from sleep.

Code

https://github.com/snehach03/week_3

How I Built It

I built Tomorrow's Tray with Google's Antigravity as my coding agent. My brief
had one priority: a smaller, scientifically honest working product is better
than an elaborate mockup.

Stack: React, TypeScript, Vite, Tailwind and Recharts on the front end;
Python, FastAPI, pandas and SQLAlchemy with SQLite on the back end. State is
stored in SQLite, not in the browser.

1. Censored demand (the core idea). Dividing sales by the fraction of the
day that has passed fails, because bakery traffic is front-loaded: most
customers come in the morning. Instead, the correction module blends two
estimates:

  • a Tobit-style conditional expectation: given that comparable uncensored days look roughly normal, it estimates what demand was, knowing it was at least what sold;
  • a diurnal correction that uses an assumed Beta-shaped customer-arrival curve between 07:00 and 17:00.

The result is never lower than what actually sold, is reported as a range, and
is labelled "limited data" when there are fewer than two comparable
uncensored days.

2. Forecasting. For each item the app forecasts tomorrow's demand with a
P10-P90 range, using empirical quantile intervals. It supports a
same-weekday-last-week baseline, a four-week same-weekday average, and a
Random Forest with lag and momentum features. A service-level setting (70, 85
or 95%) controls how much buffer goes into the suggested quantity.
TabPFN is included as an optional adapter.

3. Explanations. The backend computes the evidence and can pass it to a
local Gemma model through Ollama to turn it into one sentence. If Ollama is
not running, a deterministic template writes the explanation instead, so
nothing depends on a model being available.

4. The baker decides. Every suggested quantity can be overridden with a
note. The AI suggestion is stored next to the baker's final number and never
overwritten. The prep list exports to CSV for the kitchen.

5. Evaluation. The app has a Model Performance page with an
expanding-window backtest (the model never sees future data). It compares the
models on MAE, WAPE and RMSE, reports interval coverage, and evaluates
uncensored days separately, because sales on a sold-out day are not complete
ground truth. The repo includes 22 unit and integration tests covering CSV
validation, censored demand, forecasting, backtesting and the API.

What this does not claim:

  • It is a forecast, not a guarantee. The baker's judgement stays final.
  • The demo data is simulated, not from a real shop. For that reason I am not quoting headline accuracy numbers in this post: on simulated data they would say more about my simulator than about real bakeries.
  • The arrival curve in the correction is an assumption, not something learned from a real bakery's till.
  • I have not tested it with a real bakery yet.

Why Does Open Innovation Matter?

A bakery's sales history is private business data. Tomorrow's Tray is designed
to run entirely on the baker's own machine: the forecasting models are open
source (scikit-learn, with TabPFN as an optional open-weight adapter), the
optional explanation model is local Gemma through Ollama, and no API key or
subscription is required.

The code is MIT-licensed, so a bakery, or a developer helping one, can read
how the forecast is built, change the models, or fix the assumptions.

One honest caveat: the live demo is hosted on Render. The "your data stays
with you" benefit applies when you run the project locally from the repo.

My Agent Session

I used two prompts with Antigravity. The first was a build brief: the product,
the censored-demand module, chronological backtesting, tests, and an explicit
rule not to claim any test passed unless it was actually run, and not to
claim the model beats a baseline unless the backtest shows it.

The second set the agent's permissions. It had full autonomy inside the
project folder to install dependencies, write code, run tests and debug
without asking me each time. It was not allowed to touch anything outside the
folder (system settings, global installs, other projects), use admin rights,
or upload my files or data to external services. Deleting important data,
publishing or deploying, paid services, and sending private data to
third-party APIs still needed my approval.

Prize Categories

Top comments (0)