191 lines
11 KiB
Markdown
191 lines
11 KiB
Markdown
---
|
||
name: meal-suggestion
|
||
description: "Kitchen inventory + high-protein meal suggestions. Tracks ingredients, suggests 2 daily meals from stock, and a weekly £30 shopping list. Emails jp@txt3.com from hpm6@txt3.com. For a recovering burns victim on a high-protein diet avoiding red meat."
|
||
version: 1.0.0
|
||
author: agent
|
||
license: MIT
|
||
---
|
||
|
||
# Meal Suggestion
|
||
|
||
## Context
|
||
User **jp** is a recovering burns victim who must eat a **high-protein diet** and wants to
|
||
**avoid red meat**. This skill keeps a running kitchen inventory and produces:
|
||
|
||
- **2 daily meal suggestions** (from what's in stock) — emailed every day at 09:00.
|
||
- **A weekly shopping list** on a **£30 budget** — emailed Mondays.
|
||
|
||
- **Sender:** `hpm6@txt3.com` (the agent's Gmail, via smtp.gmail.com:587).
|
||
- **Recipient:** `jp@txt3.com`.
|
||
|
||
## Inventory
|
||
File: `/home/jp/.hermes/skills/meal-suggestion/inventory.json`
|
||
|
||
Schema:
|
||
```json
|
||
{
|
||
"updated": "YYYY-MM-DD",
|
||
"diet": { "goal": "high-protein", "avoid": ["red meat"] },
|
||
"items": [
|
||
{ "name": "Eggs", "qty": 12, "unit": "count", "category": "protein", "notes": "" }
|
||
]
|
||
}
|
||
```
|
||
- `category` is one of: `protein`, `veg`, `fruit`, `dairy`, `grain`, `tinned`,
|
||
`frozen`, `condiment`, `other`.
|
||
- Keep `qty` as a number with a `unit` (`count`, `g`, `ml`, `pack`, `can`, `tbsp`, etc.).
|
||
|
||
### Updating the inventory (you own this)
|
||
- When the user says they **used/consumed** ingredients, decrement or remove the
|
||
matching item(s) with the `patch` tool, then bump `updated` to today.
|
||
- When the user **bought** items, add or increase them.
|
||
- Do **NOT** auto-consume on a daily suggestion — the user tells you what was
|
||
actually eaten. The daily email only *proposes* meals.
|
||
|
||
## Meal suggestion rules
|
||
- Suggest **two meals** per day (e.g. lunch + dinner) using only items currently in the inventory.
|
||
- **Maximize protein** per meal; lead with a protein source.
|
||
- **Avoid red meat for PURCHASES** (beef, lamb, pork, venison, bacon, gammon) — the
|
||
weekly shopping list must NEVER suggest red meat to buy.
|
||
- **If red meat is already in the inventory, it stays usable** in daily meal
|
||
suggestions so it isn't wasted. Deprioritize it behind the high-protein
|
||
non-red-meat options, but do NOT exclude it just because it's red meat.
|
||
- Preferred proteins (lead with these): eggs, chicken, turkey, fish, prawns, tofu,
|
||
tempeh, lentils, beans, chickpeas, Greek yogurt, cottage cheese, quark, skim milk,
|
||
whey, tinned tuna/salmon, edamame, halloumi.
|
||
- **Protein target:** ~**190–200 g/day** (user ~95–100 kg × 2 g/kg — burns recovery +
|
||
preserving lean mass while losing ~15 kg fat). Aim each meal at **~90–100 g protein**
|
||
and **STATE the per-meal and daily protein totals** in the email. If 2 meals can't
|
||
reach ~190 g with current stock, say so and suggest a third hit (whey shake, extra
|
||
eggs, Greek yogurt) to close the gap.
|
||
- **Weight-loss framing:** keep meals calorie-moderate — bulk with veg, go easy on oven
|
||
chips, white bread, and oil; lead with lean protein. Fat loss comes from a mild calorie
|
||
deficit, NOT from cutting protein.
|
||
- **Note:** this is general guidance, not medical advice — defer to the user's
|
||
clinical/dietitian team and keep hydration up on a high-protein intake.
|
||
- Each meal block: **name**, the **ingredients + approx amounts** used, a short
|
||
**2–3 step method**, and the **protein total (g)**.
|
||
- If the inventory is too sparse for a real meal, say so and list the top 2–3
|
||
things to buy.
|
||
|
||
## Email format
|
||
Send via the helper (it reads SMTP creds from `~/.hermes/.env`):
|
||
```bash
|
||
python3 /home/jp/.hermes/scripts/meal/send_meal_email.py \
|
||
--subject "Your Meals for Today — <date>" \
|
||
--html /tmp/meal_today.html \
|
||
--to jp@txt3.com
|
||
```
|
||
HTML must be self-contained (inline CSS), mobile-friendly, dark-on-light, with a
|
||
header, the two meal cards, and a footer note
|
||
("Reply to tell me what you used and I'll update the inventory").
|
||
Use the scaffold in `references/email-template.md`.
|
||
|
||
## Weekly shopping list (Mondays)
|
||
- Budget **£30** total. Use realistic UK supermarket prices (Tesco/Asda/Sainsbury's).
|
||
- Prioritize protein, then veg/fruit, then staples. Show item, est. price, and a
|
||
running total that lands in range.
|
||
- Email subject: `Weekly Shopping List — <date>`.
|
||
- This does **not** modify the inventory.
|
||
- **Micronutrients & vitamins (user is 46):** you MAY include 1–2 low-price
|
||
health-support items on the weekly shop when budget allows under £30, to support
|
||
overall health alongside the high-protein diet. Sensible, evidence-aware picks for a
|
||
46-year-old on high protein with limited red meat: vitamin D (low sun exposure risk),
|
||
omega-3 (fish-oil or flax/chia), magnesium (recovery/sleep), and a B12 source if
|
||
relying on eggs/dairy over meat. Prefer food-first (oily fish, leafy greens, seeds);
|
||
only add a supplement line (e.g. "Vitamin D3 1000–2000 IU", "Omega-3 caps") when
|
||
budget permits and label it clearly as a general-health suggestion, NOT medical advice.
|
||
Keep each low-cost and behind protein + veg + staples in priority.
|
||
- **Condiments & flavourings:** you MAY include a small item or two from the
|
||
spice/sauce/condiment aisle (e.g. fresh herbs, lemon, soy, spices, stock cubes,
|
||
passata, a hot sauce) so meals are more interesting — keep each low-price and only
|
||
if budget allows under £30. These are optional "interest" buys; protein + veg +
|
||
staples come first.
|
||
|
||
## Where to shop (Eastbourne) — single-shop, per-store totals
|
||
User is in **Eastbourne**. Local options: **Lidl, Sainsbury's, Co-op, Tesco Express,
|
||
and a local Londis** (good deal on milk: 2L £1.40). Memberships: Tesco Clubcard, Co-op member.
|
||
|
||
**User preference (confirmed): Lidl is the PREFERRED shop.** It's a weekly trip so the
|
||
extra distance is acceptable; Lidl gives the best value AND leaves budget for essential
|
||
micronutrients and the occasional treat. The other stores (Tesco Express, Sainsbury's,
|
||
Co-op, Londis) are shown ONLY for comparison, and as the fallback for days he doesn't
|
||
want to make the longer journey.
|
||
|
||
Grounded in Which? 2026 monthly price index (93-item basket; Lidl £160.70 baseline):
|
||
- Lidl ≈ 1.00x — **CHEAPEST, preferred** (whey, eggs, chicken, lentils, frozen veg, milk, tuna, bananas, plus fruit/veg for micronutrients + a treat)
|
||
- Tesco superstore w/ Clubcard ≈ 1.17x; **Tesco Express** adds convenience premium → ~1.22x WITH Clubcard
|
||
- Sainsbury's w/ Nectar ≈ 1.17x
|
||
- Co-op ≈ 1.30x nominal — membership = annual dividend, not instant discount
|
||
- Londis ≈ 1.25–1.35x indicative; milk cheap but full basket pricier → top-up only
|
||
|
||
**Weekly email MUST:**
|
||
1) Build ONE single-shop basket available at **Lidl** (the default recommended shop).
|
||
2) Show a **"Same basket — where else?" comparison table** (Lidl / Tesco Express Clubcard
|
||
/ Sainsbury's Nectar / Co-op member / Londis) with estimated totals + delta vs Lidl.
|
||
Label as ESTIMATES from Which? 2026 ratios + known local prices (Londis milk £1.40),
|
||
NOT live scans. Do NOT run a live web search.
|
||
3) **Recommend Lidl** as the primary shop — note it's a weekly trip so distance is fine
|
||
and it best fits the budget incl. micronutrients/treats. List the others as fallback
|
||
only ("if you'd rather not make the trip: Tesco Express is closest").
|
||
4) Single-shop the list — don't split across stores UNLESS a specific item's local price
|
||
is **definitely known** to be lower elsewhere (e.g. Londis milk 2L at £1.40 is a
|
||
confirmed cheaper line). Estimated basket ratios alone are NOT grounds to split.
|
||
5) You MAY suggest ordering certain items via **Amazon Prime** when it's clearly better
|
||
value (e.g. whey protein 1 kg is often cheaper per gram on Prime than in-store). If
|
||
used, show the Prime item separately and note it's a delivery, not a store trip.
|
||
6) Robustness: the comparison table must be clearly visible. ALSO attach a plain-text
|
||
alternative (send_meal_email.py --text) so the comparison survives even if the mail
|
||
client strips HTML tables.
|
||
|
||
## Split-store & Amazon Prime rules
|
||
- **Default: single shop at Lidl.** Do NOT split the basket across stores based only on
|
||
the estimated Which? 2026 ratios — those are approximations. Splitting is allowed ONLY
|
||
when a **specific item's local price is definitely known** to be lower elsewhere
|
||
(e.g. Londis milk 2L at £1.40 is a confirmed cheaper line, so milk could be a Londis
|
||
top-up). State the known price when you do this.
|
||
- **Amazon Prime:** you MAY suggest ordering specific items via Amazon Prime, but ONLY
|
||
when it is **genuinely better value or more convenient** — do not assume Prime is
|
||
automatically cheaper. Reality check (2026): Lidl whey is ~£9.99/500g (≈£20/kg);
|
||
Prime branded whey (Bulk/Myprotein) is typically £18–£27/kg, so it's roughly comparable
|
||
and Lidl often wins on a single trip. Suggest Prime for whey ONLY when (a) a confirmed
|
||
deal drops it below Lidl's per-kg price, or (b) the user prefers delivery over the trip.
|
||
When suggesting, show both prices side by side and state which is cheaper. Show any
|
||
Prime item as a separate "delivered via Prime" line, distinct from the in-store Lidl list.
|
||
- When neither applies, keep everything in the one Lidl list.
|
||
|
||
## 7-day meal history (for inventory removal)
|
||
A rolling log lives at `meal-history.json` (same skill dir). The **daily job UPSERTS**
|
||
its two meal entries each run (replaces any same `date`+`meal`, so re-runs don't
|
||
duplicate) and **prunes entries older than 7 days**. Each entry:
|
||
`{ date, weekday, meal: "lunch"|"dinner", name, items: [{name, qty, unit}] }`.
|
||
Only substantive food items are logged — pure condiments (oil, salt, pepper, spices,
|
||
garlic, soy, etc.) and the optional "third hit" snack are NOT logged. Units match
|
||
`inventory.json` where possible.
|
||
|
||
**On-demand removal (user says e.g. "remove Wednesday's dinner from inventory"):**
|
||
1) Resolve the weekday/date to the matching entry (weekday is relative to today; if
|
||
ambiguous, ask). 2) For each `item` in that entry, find the matching inventory entry
|
||
by name (case-insensitive). 3) Subtract `qty`; if the result is ~0 or negative,
|
||
remove the inventory entry; else update it. 4) Skip any item NOT present in inventory
|
||
(e.g. a suggested-but-never-bought item) and say so. 5) Bump `updated` to today.
|
||
6) Confirm what was removed. The user can also say "remove all of <day>" to drop both
|
||
meals, or name a specific item to override.
|
||
|
||
## On-demand (chat)
|
||
If the user lists ingredients in chat, add them to the inventory and optionally
|
||
give an immediate 2-meal suggestion. If they ask "what should I eat today?", read
|
||
the inventory and suggest now (and offer to email it).
|
||
|
||
## Automation
|
||
Two cron jobs (created via the `cronjob` tool), both loading this skill:
|
||
- Daily 09:00 — `0 9 * * *` — 2 meal suggestions.
|
||
- Monday 08:00 — `0 8 * * 1` — weekly £30 shopping list.
|
||
|
||
Delivery is `local` because the email itself is the deliverable; check
|
||
`cronjob action=list` / logs if a send ever seems missing.
|
||
|
||
## References
|
||
- `references/protein-sources.md` — allowed proteins + example pairings.
|
||
- `references/email-template.md` — HTML email scaffold.
|