Add ideas_from_ingredients skill and job
CI / ci (push) Successful in 5m51s
CI / ci (pull_request) Successful in 5m45s

Implement the ideas_from_ingredients v1 skill on the AI harness: it asks
for 8 ideas {name, uses[], missing[], est_minutes, method, difficulty,
search_query}, keeps only "uses" entries whose harness.Normalize form is
one of the household's listed ingredients (written as the household wrote
them, in its order), drops ideas using none or repeating another, and
computes the summary line from the corrected lists.

Add internal/ideas: an ideas_from_ingredients job that grounds the ideas
with Grounder.GroundMany in the model's order until 5 are kept, drops the
ungroundable ones and, for quick_only, those whose grounded recipe is not
a Quick dinner (crockpot or minutes_total <= 30), publishing the result
as each idea is kept. POST /api/v1/ideas/from-ingredients answers 202
{jobId}.

Maestro task c3c5f98e-7f7d-4c6b-a1ab-d45bb8e497f9.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-08 19:01:03 -04:00
co-authored by Claude Opus 5.5
parent cb451baed4
commit b566be7ddc
24 changed files with 1817 additions and 25 deletions
@@ -0,0 +1,94 @@
## Instructions
You suggest dinner ideas the household can cook from the ingredients it has on hand, listed under "Ingredients on hand" in the household context.
Prefer ideas that use as many of those ingredients as possible and need as few others as possible. Pantry staples such as salt, pepper, oil and water need not be listed as missing. Vary the ideas: no two may be the same dish.
Give for each idea:
- name: the dinner's usual name, as a recipe site would title it.
- uses: the ingredients on hand the idea uses, each written exactly as it appears in the "Ingredients on hand" list. List only ingredients from that list, never one it does not hold.
- missing: the ingredients the idea needs that are not on hand, each with a quantity where it helps, e.g. "1 lime". Leave it empty when nothing is missing.
- est_minutes: your estimate of the whole minutes from starting prep to the table.
- method: how it is mainly cooked: "stovetop", "oven", "crockpot" (slow cooker or crock pot), "grill" or "other".
- difficulty: "easy", "medium" or "hard" for a home cook.
- search_query: a web search query that finds a recipe for this dinner.
One valid idea, for a household with "chicken thighs", "rice" and "cilantro" on hand (an example only, not about this household):
{"name": "Cilantro Lime Chicken and Rice", "uses": ["chicken thighs", "rice", "cilantro"], "missing": ["1 lime"], "est_minutes": 35, "method": "stovetop", "difficulty": "easy", "search_query": "cilantro lime chicken and rice recipe"}
## Household context
### Ingredients on hand
- Chicken thighs
- rice
- cilantro
- black beans
- red onion
## Output contract
This contract overrides any earlier instruction about the form of your reply. Reply with one JSON value matching the JSON Schema "ideas_from_ingredients" below, and nothing else: no prose and no Markdown code fences.
{
"type": "object",
"properties": {
"ideas": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"uses": {
"type": "array",
"items": {
"type": "string"
}
},
"missing": {
"type": "array",
"items": {
"type": "string"
}
},
"est_minutes": {
"type": "integer"
},
"method": {
"type": "string",
"enum": [
"stovetop",
"oven",
"crockpot",
"grill",
"other"
]
},
"difficulty": {
"type": "string",
"enum": [
"easy",
"medium",
"hard"
]
},
"search_query": {
"type": "string"
}
},
"required": [
"name",
"uses",
"missing",
"est_minutes",
"method",
"difficulty",
"search_query"
],
"additionalProperties": false
}
}
},
"required": [
"ideas"
],
"additionalProperties": false
}
@@ -0,0 +1 @@
Suggest 8 dinner ideas from the ingredients on hand.