Phase 3: Kiwi-specific features (recipe engine) #4

Closed
opened 2026-03-28 15:21:09 -07:00 by pyr0ball · 3 comments
Owner

Phase 3: Recipe Engine

Design spec and implementation plan complete (2026-03-30). Implementation in progress on branch feature/recipe-engine.

Design spec: circuitforge-plans/kiwi/superpowers/specs/2026-03-30-recipe-engine-design.md
Implementation plan: circuitforge-plans/kiwi/superpowers/plans/2026-03-30-recipe-engine-plan.md

What is being built

A layered recipe suggestion engine — deterministic first, LLM only when rules run out, user always approves.

8 culinary elements: Seasoning, Richness, Brightness, Method, Depth, Aroma, Structure, Texture

4 creativity levels:

  1. Library Match — corpus lookup, Free, no LLM
  2. Smart Swap — deterministic substitution via USDA FDC functional metadata, Free, no LLM
  3. LLM Assist — element scaffold → constrained LLM, Paid/BYOK
  4. Wildcard — minimal scaffold, creative latitude, experimental label, explicit opt-in, Paid

Style adapter: Cuisine-mode overlay (Italian, Latin, East Asian, Eastern European, Mediterranean) — Paid+ feature

Staple library: Free tier reference data (seitan, tempeh, firm tofu with yield formats)

Leftover mode: Moved from Premium to rate-limited Free (5/day free, unlimited Paid+)

Amendments added during implementation

Grocery list / low hanging fruit buy:

  • RecipeRequest.max_missing: int | None — filter to recipes missing at most N ingredients
  • RecipeSuggestion.missing_ingredients: list[str] — what to buy for that recipe
  • RecipeResult.grocery_list: list[str] — aggregated shopping list across suggestions

Hard day mode (accessibility):

  • RecipeRequest.hard_day_mode: bool = False — for depleted users, only show easy-method recipes
  • Method complexity classified from directions text: easy (microwave, mix, stir, toast, blend, assemble) / moderate / involved
  • Equipment list read from user profile, not per-request

User settings — cooking equipment profile (Task 15, new):

  • Migration 012: user_settings key-value table (TEXT key, JSON TEXT value)
  • cooking_equipment key stores ["microwave", "toaster", ...]
  • GET/PUT /settings endpoint
  • When hard_day_mode=True, engine reads equipment from settings to expand what qualifies as easy
  • Aligns with CF accessibility mission (neurodivergent/adaptive needs users)

Implementation progress

  • Task 1: Pipeline dependencies installed
  • Task 2: Migrations 006-011 (+ 005 bug fix)
  • Task 3: USDA FDC pipeline scripts + tests
  • Task 4: FlavorGraph importer
  • Task 5: Recipe corpus + substitution pairs
  • Task 6: tiers.py updates
  • Task 7: ElementClassifier
  • Task 8: SubstitutionEngine
  • Task 9: Staple library
  • Task 10: Store methods
  • Task 11: RecipeEngine Levels 1-2 + grocery list + hard day mode
  • Task 12: Recipe + staple API endpoints
  • Task 13: StyleAdapter + 5 cuisine templates
  • Task 14: LLMRecipeGenerator Levels 3-4
  • Task 15: User settings (cooking equipment profile)
  • Phase 7: Run data pipeline

Data sources

  • AkashPS11/recipes_data_food.com (MIT) — 1.05M recipes, primary corpus
  • omid5/usda-fdc-foods-cleaned (CC0) — functional submetadata base
  • FlavorGraph (lamypark/FlavorGraph, research) — flavor molecule graph
  • alexdseo/RecipeBERT (Apache 2.0) — ingredient similarity
  • flax-community/t5-recipe-generation — recipe generation backbone
  • lishuyang/recipepairs (GPL-3.0 WARNING) — derive substitution pairs only, do not ship raw data

Deferred

  • Multi-stage recipes (DAG -- e.g. Beef Wellington) -- Phase 4 separate design pass
## Phase 3: Recipe Engine Design spec and implementation plan complete (2026-03-30). Implementation in progress on branch `feature/recipe-engine`. **Design spec:** `circuitforge-plans/kiwi/superpowers/specs/2026-03-30-recipe-engine-design.md` **Implementation plan:** `circuitforge-plans/kiwi/superpowers/plans/2026-03-30-recipe-engine-plan.md` ### What is being built A layered recipe suggestion engine — deterministic first, LLM only when rules run out, user always approves. **8 culinary elements:** Seasoning, Richness, Brightness, Method, Depth, Aroma, Structure, Texture **4 creativity levels:** 1. Library Match — corpus lookup, Free, no LLM 2. Smart Swap — deterministic substitution via USDA FDC functional metadata, Free, no LLM 3. LLM Assist — element scaffold → constrained LLM, Paid/BYOK 4. Wildcard — minimal scaffold, creative latitude, experimental label, explicit opt-in, Paid **Style adapter:** Cuisine-mode overlay (Italian, Latin, East Asian, Eastern European, Mediterranean) — Paid+ feature **Staple library:** Free tier reference data (seitan, tempeh, firm tofu with yield formats) **Leftover mode:** Moved from Premium to rate-limited Free (5/day free, unlimited Paid+) ### Amendments added during implementation **Grocery list / low hanging fruit buy:** - `RecipeRequest.max_missing: int | None` — filter to recipes missing at most N ingredients - `RecipeSuggestion.missing_ingredients: list[str]` — what to buy for that recipe - `RecipeResult.grocery_list: list[str]` — aggregated shopping list across suggestions **Hard day mode (accessibility):** - `RecipeRequest.hard_day_mode: bool = False` — for depleted users, only show easy-method recipes - Method complexity classified from directions text: easy (microwave, mix, stir, toast, blend, assemble) / moderate / involved - Equipment list read from user profile, not per-request **User settings — cooking equipment profile (Task 15, new):** - Migration 012: `user_settings` key-value table (TEXT key, JSON TEXT value) - `cooking_equipment` key stores `["microwave", "toaster", ...]` - `GET/PUT /settings` endpoint - When `hard_day_mode=True`, engine reads equipment from settings to expand what qualifies as easy - Aligns with CF accessibility mission (neurodivergent/adaptive needs users) ### Implementation progress - [x] Task 1: Pipeline dependencies installed - [x] Task 2: Migrations 006-011 (+ 005 bug fix) - [x] Task 3: USDA FDC pipeline scripts + tests - [ ] Task 4: FlavorGraph importer - [ ] Task 5: Recipe corpus + substitution pairs - [ ] Task 6: tiers.py updates - [ ] Task 7: ElementClassifier - [ ] Task 8: SubstitutionEngine - [ ] Task 9: Staple library - [ ] Task 10: Store methods - [ ] Task 11: RecipeEngine Levels 1-2 + grocery list + hard day mode - [ ] Task 12: Recipe + staple API endpoints - [ ] Task 13: StyleAdapter + 5 cuisine templates - [ ] Task 14: LLMRecipeGenerator Levels 3-4 - [ ] Task 15: User settings (cooking equipment profile) - [ ] Phase 7: Run data pipeline ### Data sources - `AkashPS11/recipes_data_food.com` (MIT) — 1.05M recipes, primary corpus - `omid5/usda-fdc-foods-cleaned` (CC0) — functional submetadata base - `FlavorGraph` (lamypark/FlavorGraph, research) — flavor molecule graph - `alexdseo/RecipeBERT` (Apache 2.0) — ingredient similarity - `flax-community/t5-recipe-generation` — recipe generation backbone - `lishuyang/recipepairs` (GPL-3.0 WARNING) — derive substitution pairs only, do not ship raw data ### Deferred - Multi-stage recipes (DAG -- e.g. Beef Wellington) -- Phase 4 separate design pass
pyr0ball added this to the Alpha milestone 2026-03-28 15:21:09 -07:00
pyr0ball modified the milestone from Alpha to Beta — Recipe Suggestions 2026-03-29 20:05:41 -07:00
Author
Owner

Amendment: Affiliate grocery links (2026-03-31)

Adding grocery delivery affiliate links to the missing-ingredient grocery list feature.

Design:

  • GroceryLink schema: ingredient, retailer, url
  • RecipeResult.grocery_links: list[GroceryLink] — populated alongside grocery_list
  • New service: app/services/recipe/grocery_links.pyGroceryLinkBuilder

Tier split:

  • Free: URL construction only — affiliate deeplinks (Amazon Fresh, Walmart, Instacart). Affiliate IDs from env vars (AMAZON_AFFILIATE_TAG, INSTACART_AFFILIATE_ID). Empty string = retailer disabled.
  • Paid+: Live product search API (Instacart/Kroger) — stubbed in Task 11, full implementation as future task.

Ideated by Daniel. Folding into Task 11 implementation.

**Amendment: Affiliate grocery links** (2026-03-31) Adding grocery delivery affiliate links to the missing-ingredient grocery list feature. **Design:** - `GroceryLink` schema: `ingredient`, `retailer`, `url` - `RecipeResult.grocery_links: list[GroceryLink]` — populated alongside `grocery_list` - New service: `app/services/recipe/grocery_links.py` — `GroceryLinkBuilder` **Tier split:** - **Free**: URL construction only — affiliate deeplinks (Amazon Fresh, Walmart, Instacart). Affiliate IDs from env vars (`AMAZON_AFFILIATE_TAG`, `INSTACART_AFFILIATE_ID`). Empty string = retailer disabled. - **Paid+**: Live product search API (Instacart/Kroger) — stubbed in Task 11, full implementation as future task. Ideated by Daniel. Folding into Task 11 implementation.
Author
Owner

Phase 3 — Recipe Engine Complete ✓

All 15 tasks implemented and merged to main (2026-03-31)

What shipped

  • Data pipeline: USDA FDC ingredient index, FlavorGraph molecule index, food.com recipe corpus (1.05M), substitution pair derivation (GPL-safe)
  • ElementClassifier: ingredient → 8 culinary element tagging (heuristic + FlavorGraph)
  • SubstitutionEngine: deterministic Level 2 swaps with CompensationHints (fat/glutamate/moisture thresholds)
  • RecipeEngine Levels 1–2: corpus match + substitution, hard day mode (equipment-filtered), grocery list + affiliate deeplinks (Amazon Fresh, Walmart, Instacart)
  • RecipeEngine Levels 3–4: LLMRecipeGenerator with element-scaffold prompt (Level 3) and wildcard prompt (Level 4, <1500 chars)
  • StyleAdapter: 5 cuisine templates (Italian, Latin, East Asian, Eastern European, Mediterranean) with weighted method biases, element-filtered aromatics/depth/structure
  • User settings: cooking_equipment key-value store, wired into hard day mode
  • API endpoints: POST /recipes/suggest, GET /recipes/{id}, GET /staples/, GET/PUT /settings/{key}
  • Migrations: 006–012 (element_profiles, recipe_corpus, substitution_pairs, staple_library, recipe_feedback, rate_limits, user_settings) + 013 (background_tasks from task-scheduler branch)

55 recipe engine tests + 8 task scheduler tests = 63 passing

Tier gating

  • Levels 1–2 + grocery links + hard day mode: Free
  • Levels 3–4 (LLM): Paid or BYOK-unlockable
  • Style picker: Paid+
  • Rate limiting: 5/day free, unlimited Paid+

Still pending (Phase 4)

  • Data pipeline execution (~10GB datasets — manual run required)
  • Multi-stage recipes (DAG, e.g. Beef Wellington)
  • Live grocery search API (Paid+ stub in grocery_links.py)
  • SQLCipher per-user DB encryption (deferred from Phase 2)

Cloud instance rebuilt and live at https://menagerie.circuitforge.tech/kiwi

## Phase 3 — Recipe Engine Complete ✓ **All 15 tasks implemented and merged to main (2026-03-31)** ### What shipped - **Data pipeline**: USDA FDC ingredient index, FlavorGraph molecule index, food.com recipe corpus (1.05M), substitution pair derivation (GPL-safe) - **ElementClassifier**: ingredient → 8 culinary element tagging (heuristic + FlavorGraph) - **SubstitutionEngine**: deterministic Level 2 swaps with CompensationHints (fat/glutamate/moisture thresholds) - **RecipeEngine Levels 1–2**: corpus match + substitution, hard day mode (equipment-filtered), grocery list + affiliate deeplinks (Amazon Fresh, Walmart, Instacart) - **RecipeEngine Levels 3–4**: LLMRecipeGenerator with element-scaffold prompt (Level 3) and wildcard prompt (Level 4, <1500 chars) - **StyleAdapter**: 5 cuisine templates (Italian, Latin, East Asian, Eastern European, Mediterranean) with weighted method biases, element-filtered aromatics/depth/structure - **User settings**: `cooking_equipment` key-value store, wired into hard day mode - **API endpoints**: `POST /recipes/suggest`, `GET /recipes/{id}`, `GET /staples/`, `GET/PUT /settings/{key}` - **Migrations**: 006–012 (element_profiles, recipe_corpus, substitution_pairs, staple_library, recipe_feedback, rate_limits, user_settings) + 013 (background_tasks from task-scheduler branch) **55 recipe engine tests + 8 task scheduler tests = 63 passing** ### Tier gating - Levels 1–2 + grocery links + hard day mode: **Free** - Levels 3–4 (LLM): **Paid or BYOK-unlockable** - Style picker: **Paid+** - Rate limiting: 5/day free, unlimited Paid+ ### Still pending (Phase 4) - Data pipeline execution (~10GB datasets — manual run required) - Multi-stage recipes (DAG, e.g. Beef Wellington) - Live grocery search API (Paid+ stub in `grocery_links.py`) - SQLCipher per-user DB encryption (deferred from Phase 2) Cloud instance rebuilt and live at https://menagerie.circuitforge.tech/kiwi
Author
Owner

Closing — recipe engine fully implemented:

  • Levels 1-4 (corpus match, LLM assist, style adapter)
  • Dietary constraints + allergies
  • Assembly template system (13 templates: burrito, stir fry, soup/stew, etc.)
  • Nutrition panel with macro estimates
  • Ingredient prep-note reconstruction
  • FTS synonym expansion, alt-meat/alt-chicken support
  • Style picker, expiry-first, hard day mode, wildcard

Shipped in feature/orch-auto-lifecycle.

Closing — recipe engine fully implemented: - Levels 1-4 (corpus match, LLM assist, style adapter) - Dietary constraints + allergies - Assembly template system (13 templates: burrito, stir fry, soup/stew, etc.) - Nutrition panel with macro estimates - Ingredient prep-note reconstruction - FTS synonym expansion, alt-meat/alt-chicken support - Style picker, expiry-first, hard day mode, wildcard Shipped in `feature/orch-auto-lifecycle`.
Sign in to join this conversation.
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: Circuit-Forge/kiwi#4
No description provided.