cauldron/cauldron
Sulkta 8a82b66de1 recipe enrichment: per-recipe Sonnet meta for smarter planning
The 'fancy data fun' Alice wanted: pre-compute structured metadata for
every recipe so the plan generator can match preferences to actual
recipe characteristics, not just match keywords on names.

Sonnet returns per recipe:
  - tags[]: curated descriptors (high-protein, weeknight, one-pan,
    leftovers-good, kid-friendly, etc — picks 3-8 that genuinely apply)
  - cuisine, complexity (easy/medium/involved), estimated_minutes
  - meal_type (breakfast/lunch/dinner/snack/dessert/side/sauce/drink)
  - primary_protein (chicken/beef/pork/fish/seafood/tofu/...)
  - primary_carb (rice/pasta/bread/potato/tortilla/quinoa/...)
  - veg_forward (veg-forward/mixed/meat-forward)
  - comfort_tier (weeknight-easy/hearty-comfort/fancy-occasion/...)
  - season_fit[] + summary one-liner + best_for short phrase

Schema:
- Migration 024: cauldron_recipe_meta keyed by (household_id, recipe_slug),
  meta_json + enrich_version (bumping the version invalidates the cache
  and forces re-walk). One row per Mealie recipe Alice owns.
- Migration 025: cauldron_enrich_jobs — job runner state. No
  proposals/review needed since metadata is purely additive.

Forge:
- enrich_recipe(recipe) builds a compact prompt with name + description
  + ingredients + steps (capped at 2000 chars total) + yields, asks
  Sonnet for the structured blob. _extract_recipe_meta validates and
  coerces types.

Module enrich_recipes.py:
- Daemon thread runner, walks all household recipes, skips already-
  enriched at current ENRICH_VERSION (idempotent), respects external
  cancel + stuck-job recovery. Skips cross-household recipes (Lake
  another household stuff visible but not enrichable).

Plan generator hookup:
- /api/plan/generate + regenerate now pulls cauldron_recipe_meta and
  splices it into the recipe pool prompt. Each pool line goes from:
      - chicken-stir-fry: Chicken Stir Fry  [asian]
  to:
      - chicken-stir-fry: Chicken Stir Fry  [asian · easy · 30min ·
        protein:chicken · carb:rice · high-protein/weeknight/one-pan]
        quick weeknight stir-fry with leftover-friendly portions
  Sonnet now has rich attributes to actually match a 'high protein
  week' or 'comfort food' or 'quick' preference against, instead of
  guessing from titles.

Endpoints:
- /enrich-recipes UI page (progress bar + start + force re-enrich +
  cancel; no review/approve since meta is additive)
- /api/recipes/enrich-{start,status,cancel} session-authed
- /api/admin/recipes/enrich-start bearer-authed for the operator kick-off

Cost (one-time): ~5s/recipe × 226 = ~20 min walk. Subsequent runs
only process new/changed recipes.
2026-04-30 20:08:20 -07:00
..
data v0.3 step 5: lean shopping list — claude on-demand foods + game strip 2026-04-29 22:02:20 -07:00
templates recipe enrichment: per-recipe Sonnet meta for smarter planning 2026-04-30 20:08:20 -07:00
__init__.py v0.1 — backend bones + ingredient sterilizer 2026-04-28 16:59:11 -07:00
aggregator.py Step 2: re-key cauldron's food metadata by mealie_food_id 2026-04-30 11:52:25 -07:00
bulk_sterilize.py sterilize bulk: respect external cancel mid-loop 2026-04-30 10:02:53 -07:00
config.py fix: split MEALIE_API_URL (internal) from MEALIE_PUBLIC_URL (UI link) 2026-04-28 20:26:25 -07:00
consolidate_foods.py consolidate: pair-based clustering instead of single-link agglomerative 2026-04-30 19:51:59 -07:00
crypto.py v0.2 foundation — Authentik OIDC + mariadb DB + Fernet crypto 2026-04-28 19:47:47 -07:00
db.py recipe enrichment: per-recipe Sonnet meta for smarter planning 2026-04-30 20:08:20 -07:00
dedupe_recipes.py recipe dedupe: cluster + Sonnet decide + DELETE via Mealie 2026-04-30 18:16:56 -07:00
enrich_recipes.py recipe enrichment: per-recipe Sonnet meta for smarter planning 2026-04-30 20:08:20 -07:00
foods.py Step 2: re-key cauldron's food metadata by mealie_food_id 2026-04-30 11:52:25 -07:00
forge.py recipe enrichment: per-recipe Sonnet meta for smarter planning 2026-04-30 20:08:20 -07:00
mealie.py recipe dedupe: cluster + Sonnet decide + DELETE via Mealie 2026-04-30 18:16:56 -07:00
oidc.py v0.2 foundation — Authentik OIDC + mariadb DB + Fernet crypto 2026-04-28 19:47:47 -07:00
recipe_index.py search: local fuzzy recipe index — way smarter than Mealie's lexical default 2026-04-28 21:37:12 -07:00
server.py recipe enrichment: per-recipe Sonnet meta for smarter planning 2026-04-30 20:08:20 -07:00
sterilizer.py sterilize hot-fixes: 300s timeout + defensive string→dict parsing 2026-04-30 12:41:58 -07:00