Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle Submission 💸
The Problem
Every evening, WhatsApp groups across Indian neighbourhoods fill up with messages like:
[14/10/26, 9:12 PM] Priya Sharma: kal 2 veg thali lunch, no onion
[14/10/26, 9:40 PM] Rahul Verma: parso ka dabba cancel kar do
[14/10/26, 10:05 PM] Megha Jain: kal se 6 din band, bahar ja rahe
[14/10/26, 10:31 PM] Harsh Khan: 1 dabba kl afternoon 12 bje
For a home tiffin business, these are not casual messages. They are tomorrow’s production plan.
The owner has to understand the Hinglish, resolve words like kal and parso, remember each customer’s usual dish, count the orders, and decide how much food to prepare before sunrise.
Cook too much, and food and profit go to waste.
Cook too little, and a regular customer may order somewhere else.
Most small tiffin kitchens still manage this process with a notebook, a calculator, and memory.
That is the problem Dabba is designed to solve.
What I Built
Dabba converts a WhatsApp conversation into a structured order list and a practical kitchen prep plan.
The workflow is:
- Paste the evening’s WhatsApp messages.
- Parse each message into a structured order.
- Resolve relative dates such as
kal,parso, andMonday. - Use kitchen memory to understand customer-specific phrases like
1 dabba. - Forecast the final demand for each dish and meal.
- Show the owner how many portions to cook, along with a confidence range.
For example, Dabba knows that Harsh’s simple message, 1 dabba, usually means a paneer thali. It can also understand that Megha’s “six days off” means fewer orders every day until she returns.
The final result is a prep list such as:
Paneer thali Cook 34 Possible range: 31–38
Veg thali Cook 22 Possible range: 20–25
Rajma rice Cook 16 Possible range: 14–18
Rotis 86
The goal is simple: help a small kitchen make better decisions before the cooking starts.
Demo
Dabba demo: paste a WhatsApp group, generate orders, and update kitchen memory
Hosted demo: https://dabba-jgho.onrender.com
The free Render instance may take about a minute to wake up.
Press Use tonight’s sample to load twelve example messages. Dabba parses the messages in roughly 12 seconds and generates a prep plan in about 30 seconds.
The most important demo interaction is the correction flow:
- Harsh’s
1 dabbais initially interpreted as the wrong dish. - The owner changes it to a paneer thali.
- Dabba stores that correction as kitchen memory.
- The next time Harsh writes
1 dabba, Dabba remembers that he usually wants paneer.
Code
Dabba — kitchen operations for a home tiffin business
Dabba combines three components:
- Order parsing: Qwen3.5-4B fine-tuned with a LoRA adapter using Tinker.
- Demand forecasting: TabPFN predicts tomorrow’s demand for each dish and meal.
- Kitchen memory: Backboard stores customer preferences and past corrections.
- Deployment: The web app runs on Render.
Basic setup:
uv venv --python 3.12
uv pip install -r requirements-train.txt
cp .env.example .env
Set the required environment variables:
TINKER_API_KEY
BACKBOARD_API_KEY
TABPFN_TOKEN
Then generate the simulated kitchen data:
.venv/bin/python data/simulate.py
The complete source code is available on GitHub:
How It Works
1. Parsing messy WhatsApp messages with a fine-tuned 4B model
The difficult part is not recognizing words such as thali or lunch.
The difficult part is understanding the context.
Kal means tomorrow, but tomorrow depends on the date attached to that particular WhatsApp message.
Parso means the day after tomorrow.
A message sent on Thursday saying Monday refers to a different date than the same message sent on Sunday.
A general-purpose model has to calculate all of this each time. Dabba’s parser was trained on examples where these relationships are explicit.
I generated the training data from a simulated tiffin kitchen. Eighty customers have different:
- Usual dishes
- Meal preferences
- Office days
- Travel breaks
- Delivery times
- Ordering habits
- Churn patterns
The simulator produced five months of orders. Each order was then converted into a WhatsApp-style message using Hinglish, English, and Roman Hindi templates.
Because the program generated both the message and the label, the training labels were exact. Around one-quarter of the messages also included realistic typos, lowercase text, and informal spelling.
The model was trained with a standard Tinker loop:
tc = service.create_lora_training_client(
base_model="Qwen/Qwen3.5-4B",
rank=16,
)
renderer = get_renderer(
"qwen3_5_disable_thinking",
tc.get_tokenizer(),
)
for step in range(129):
tc.forward_backward(batch(step), "cross_entropy")
tc.optim_step(
adam_params=tinker.AdamParams(
learning_rate=lr(step)
)
)
sampler_path = tc.save_weights_for_sampler(
name="dabba-v2"
).result().path
The training used three epochs and 129 steps. The total training cost was under two dollars.
Evaluation
I evaluated the models on the same 200 held-out messages.
The baselines were zero-shot versions of the original Qwen3.5-4B model and gpt-oss-120b.
| System | Valid JSON | Action | Date | Items | Preferences | Time | All fields | P50 latency | Cost / 1k messages |
|---|---|---|---|---|---|---|---|---|---|
| Qwen3.5-4B zero-shot | 72% | 56% | 56% | 53% | 67% | 66% | 30% | 2.1 s | $0.52 |
| gpt-oss-120b zero-shot | 98% | 96% | 50% | 86% | 96% | 96% | 38% | 2.8 s | $0.56 |
| Qwen3.5-4B + Dabba LoRA | 100% | 100% | 100% | 100% | 100% | 99% | 98% | 2.3 s | $0.49 |
The larger model produced valid JSON more consistently, but it struggled with relative dates. The fine-tuned 4B model performed much better on the actual task because it had learned the structure of these messages.
The four missed examples from the fine-tuned model were caused by:
- Two templates where the delivery time was missing from the message
- One dropped
jainpreference - One date error involving
kalfrom the night of 30 May
All-fields and items accuracy on 200 held-out messages
2. Kitchen memory with Backboard
A language model cannot know that Harsh’s 1 dabba means paneer.
That information belongs to the kitchen.
When the owner corrects an order, Dabba stores a simple memory in Backboard:
POST /assistants/{id}/memories
{
"content": "Harsh Khan: usual dish paneer_thali, prefs no_onion."
}
Before parsing a new message, Dabba searches the kitchen memories using the sender and message text. It keeps only memories that belong to that customer and adds them to the prompt under a section called:
Known rules from the kitchen
There is no extra language model involved in storing or retrieving these facts. They are treated as structured operational knowledge.
On 35 test messages where regular customers wrote only dabba, the fine-tuned parser selected the correct dish 100% of the time when the relevant kitchen memory was available.
That is the kind of information a model should not have to guess.
3. Forecasting tomorrow’s demand with TabPFN
At around 9 pm, the kitchen has three important pieces of information:
- Historical sales for each dish
- The date and weekday for tomorrow
- The orders already booked for tomorrow
The advance orders are especially useful. They are a known future signal, so I included them as a feature in the forecasting model.
For each dish and meal, Dabba builds features such as:
day of week
day of month
holiday indicator
Navratri indicator
advance orders
lag 1
lag 7
lag 14
7-day average demand
28-day average demand
7-day average advance orders
advance-order share
Rain is present in the historical data but deliberately excluded from the feature set. At 9 pm, the owner does not reliably know tomorrow’s weather, so the model should not use information that would not be available at decision time.
The model is a TabPFNRegressor from Prior Labs. It is fitted on the historical data and asked for the 10th, 50th, and 90th percentile predictions.
I evaluated the model over the last 28 days using walk-forward validation and compared it with the rules of thumb a kitchen owner might normally use.
| Predictor | MAE in dabbas | Over-cooked / day | Under-cooked / day | Exactly right |
|---|---|---|---|---|
| Same as yesterday | 2.56 | 18.1 | 17.7 | 24% |
| 7-day average | 2.30 | 15.7 | 16.5 | 26% |
| Same weekday last week | 1.79 | 12.6 | 12.5 | 32% |
| Advance orders ÷ usual advance share | 1.55 | 12.4 | 9.3 | 36% |
| Gradient boosting | 1.07 | 7.3 | 7.7 | 39% |
| TabPFN | 0.90 | 3.9 | 8.7 | 51% |
The evaluation contained 392 dish-day predictions across 14 dish-and-meal series.
Actual demand versus TabPFN’s median prediction and 10–90% range
The important business metric is not only MAE.
For a kitchen, overproduction and underproduction have different costs. Extra food becomes waste, while cooking slightly more can prevent a missed order.
The owner’s rule mis-cooked roughly 22 dabbas per day across the menu. TabPFN reduced that to around 13. Its predictions still leaned slightly toward underproduction, so the app uses the upper part of the prediction range when extra cooking is relatively inexpensive.
One limitation is worth calling out: the requested 10–90% prediction band covered 97% of the observed outcomes. The interval is therefore wider than its nominal confidence level suggests.
For this use case, wider bands are safer than false precision, but the calibration still needs improvement.
4. Hosting on Render
The hosted version runs as a single Python web service on Render.
The 4B parser is accessed through Tinker’s sampling API because the free 512 MB service cannot hold the model locally. TabPFN also runs through Prior Labs’ API for the same reason.
The repository includes support for alternative local configurations:
- Ollama for running the parser locally
- Local TabPFN weights for offline forecasting
The hosted version was the one I measured for this submission, but the local path is important for kitchens that do not want customer messages leaving the house.
Why Open Innovation Matters Here
Small models can be enough
The fine-tuned 4B model beat the much larger zero-shot model on this specific task.
The reason was not raw scale. It was specialization.
A small adapter trained on the language, date expressions, and ordering patterns of a tiffin kitchen was more useful than a much larger model that had not seen the task in the same way.
The kitchen can keep its own data
WhatsApp messages contain names, routines, preferences, travel plans, and delivery information.
That data should not automatically become part of somebody else’s model or cloud system.
Dabba can run with a local parser and local forecasting components, giving the kitchen a path toward keeping its operational data in-house.
Forecasting should be accessible
Demand forecasting is usually associated with large companies, data teams, and expensive infrastructure.
TabPFN makes it possible to fit a useful tabular model on a relatively small dataset without building a large forecasting pipeline from scratch.
The owner does not need to see the model internals. They need an answer such as:
Cook 34 portions.
Likely range: 31–38.
That is the useful abstraction.
Honest Limitations
The kitchen is simulated.
The customers, habits, festival effects, and demand patterns were generated by me. The parser’s messages also come from 26 templates across three language registers.
The test set was held out, but it still comes from the same simulated distribution.
That means the results show that the method works on a realistic prototype workload. They do not prove that it will work equally well for every real kitchen.
The next step is collecting more real, anonymised examples from different tiffin services.
My First Real User
I tested Dabba with a two-person tiffin kitchen near my flat. The kitchen uses one WhatsApp group and a notebook.
I received eleven messages with the names changed. All eleven were parsed successfully.
One regular customer’s 1 dabba was initially interpreted as a veg thali, even though he normally orders rajma. The owner corrected the row, Dabba stored the correction, and the next two messages from that customer were interpreted as rajma.
The correction flow worked exactly as intended.
Interestingly, the owner’s first feature request was not the forecast.
She wanted a printable delivery list with:
- Customer name
- Dish
- Quantity
- Delivery time
- Preferences such as
no onion
That is a small feature, but it is also a useful reminder that the best product roadmap usually comes from watching someone use the tool.
Her next request was:
“Agar yeh bill bhi bana de.”
In English: “It would be great if it could make the monthly bill too.”
That is probably the next feature.
My Agent Session
I built Dabba with Claude Code over three evenings.
The session covered:
- The kitchen simulator
- Training data generation
- Tinker fine-tuning
- TabPFN forecasting
- Backboard memory
- The web interface
- Render deployment
- Evaluation scripts
- Debugging two labelling issues
The agent also helped identify bugs by inspecting the error files instead of assuming the first result was correct.
Prize Categories
- Thinking Machines — Tinker
- Prior Labs — TabPFN
- Render
- Backboard
Dabba is a small tool for a very practical problem: helping a local kitchen decide what to cook tomorrow morning.
Top comments (1)
Great