meal-planning

star 1

Meal plans, recipes, and recipe favorites. Load this skill when the user asks for: plan repas / meal plan, recette / recipe, idée de plat / dish idea / suggestion, menu de la semaine / weekly menu, "génère un plan" / "create a plan", recette spécifique (e.g. "crêpes au saumon", "poulet curry"), gérer favoris / manage favorites — ajouter / save / "add to favorites", lister / list / "mes favoris" / "my favorites", chercher / find / "trouve la recette", supprimer / delete / remove a favorite. 2 routes: DB recipes (fast default) or custom LLM (when a specific dish is named).

mzt-76 By mzt-76 schedule Updated 5/26/2026

name: meal-planning description: >- Meal plans, recipes, and recipe favorites. Load this skill when the user asks for: plan repas / meal plan, recette / recipe, idée de plat / dish idea / suggestion, menu de la semaine / weekly menu, "génère un plan" / "create a plan", recette spécifique (e.g. "crêpes au saumon", "poulet curry"), gérer favoris / manage favorites — ajouter / save / "add to favorites", lister / list / "mes favoris" / "my favorites", chercher / find / "trouve la recette", supprimer / delete / remove a favorite. 2 routes: DB recipes (fast default) or custom LLM (when a specific dish is named).

category: planning

Meal Planning

Quand utiliser

  • Demande de plan de repas (1+ jours)
  • Demande de recette spécifique
  • Récupération d'un plan existant
  • Ajouter une recette en favoris / sauvegarder une recette
  • Consulter ses recettes favorites / mes favoris / mes recettes sauvegardées
  • Retrouver une recette favorite par nom
  • Supprimer un favori / retirer une recette des favoris

Comportement agent

  • TOUJOURS poser 1 question groupée avant de générer, sauf si l'utilisateur dit explicitement "go" / "lance" / "par défaut". La question doit couvrir :
    1. Durée : combien de jours ? (défaut 3)
    2. Batch cooking : préparer les mêmes plats plusieurs jours ? Si oui, combien ?
    3. Préférences repas : un plat ou ingrédient spécifique ? (petit-déj, déjeuner, dîner)
    4. Variété petit-déj : même petit-déj chaque jour ou varier ?
  • Si "go", "lance", "génère" sans contexte → défauts automatiques, exécution immédiate
  • Défaut : 3 jours, même petit-déj, repas variés, PAS de batch cooking (chaque repas est différent sauf le petit-déj). Ne PAS passer batch_days sauf si l'utilisateur le demande explicitement.
  • JAMAIS annoncer des recettes avant la génération
  • JAMAIS improviser une recette en texte — toujours via script
  • JAMAIS retenter un appel run_skill_script simplifié après une erreur de validation (Pydantic, JSON Schema). Si un param est rejeté, arrêter et dire à l'utilisateur : "Je n'ai pas pu appliquer ta demande [détail]. Veux-tu que je réessaie autrement ?"
  • JAMAIS décrire dans le chat des plats absents du JSON retourné par le script. Le résumé doit refléter exactement meal_plan.days[] — pas la demande initiale de l'utilisateur si elle n'a pas été honorée.
  • Toute recette générée a un recipe.id — le conserver pour la liste de courses

2 routes de génération

Route 1 : Recettes DB (défaut)

  • Aucune préférence spécifique → le script pioche dans la recipe DB
  • Rapide, pas d'appel LLM
  • Scaling mathématique pour atteindre les macros cibles

Route 2 : Recettes custom (LLM)

  • L'utilisateur mentionne un plat ou ingrédient spécifique → route LLM
  • Passer via meal_preferences → déclenche generate_custom_recipe (Claude Haiku 4.5)
  • Recette sauvegardée en DB pour réutilisation future

Règle clé — recette custom + plan : quand l'utilisateur demande un plan incluant une recette custom générée dans la conversation (qui a un recipe_id), d'abord appeler add_favorite_recipe avec ce recipe_id, puis generate_week_plan avec une entrée meals[] scope="day" (ou scope="all") référençant le nom de la recette. Le pipeline retrouvera la recette via le lookup favoris.

Règle clé : toute mention de plat ou d'ingrédient spécifique = route custom.

  • "fais-moi un plan" → route DB (pas de meals[])
  • "je veux de la baguette le matin" → meals: [{meal_type: "petit-dejeuner", scope: "all", request: "baguette et chocolat chaud"}]
  • "risotto mardi" → meals: [{meal_type: "dejeuner", scope: "day", day: "Mardi", request: "risotto"}]

Scripts (appels agent)

Script Quand
generate_week_plan Générer un plan (1-7 jours)
generate_custom_recipe Recette unique sur demande
fetch_stored_meal_plan Récupérer un plan existant
add_favorite_recipe Ajouter une recette aux favoris de l'utilisateur
get_user_favorites Lister les recettes favorites avec macros + ingredients (filtre optionnel par nom)
remove_favorite_recipe Supprimer une recette des favoris
# Plan par défaut (1 jour)
run_skill_script("meal-planning", "generate_week_plan", {})

# Plan 7 jours avec préférence globale (même plat TOUS les jours)
run_skill_script("meal-planning", "generate_week_plan", {
    "num_days": 7,
    "meals": [
        {"meal_type": "petit-dejeuner", "scope": "all",
         "request": "omelette aux oeufs et épinards"}
    ]
})

# Plan avec demande pour un JOUR + REPAS spécifique
run_skill_script("meal-planning", "generate_week_plan", {
    "num_days": 3,
    "meals": [
        {"meal_type": "dejeuner", "scope": "day", "day": "Mardi",
         "request": "poulet ratatouille pommes de terre"},
        {"meal_type": "diner", "scope": "day", "day": "Mercredi",
         "request": "saumon grillé avec légumes"}
    ]
})

# Batch cooking 3 jours avec plat précis (résout Bug C)
run_skill_script("meal-planning", "generate_week_plan", {
    "num_days": 7,
    "meals": [
        {"meal_type": "dejeuner", "scope": "batch", "days": 3,
         "request": "poulet ratatouille"}
    ]
})

# Combiné : matin global + batch midi + override soir
run_skill_script("meal-planning", "generate_week_plan", {
    "num_days": 7,
    "meals": [
        {"meal_type": "petit-dejeuner", "scope": "all", "request": "porridge protéiné"},
        {"meal_type": "dejeuner", "scope": "batch", "days": 3, "request": "poulet curry"},
        {"meal_type": "diner", "scope": "day", "day": "Vendredi", "request": "saumon grillé"}
    ]
})

# Recette sur demande
run_skill_script("meal-planning", "generate_custom_recipe", {
    "recipe_request": "salade niçoise protéinée",
    "meal_type": "dejeuner"
})
# ENUM meal_type : "petit-dejeuner" | "dejeuner" | "diner" | "collation"
# After: include the `ui_marker` field from the response verbatim at END of your text

# Récupérer un plan existant
run_skill_script("meal-planning", "fetch_stored_meal_plan", {"week_start": "2026-02-23"})

# Ajouter une recette aux favoris (recipe_id vient de generate_custom_recipe)
run_skill_script("meal-planning", "add_favorite_recipe", {
    "recipe_id": "abc-123-uuid",
    "notes": "Ma recette d'escalope maison"
})

# Lister tous les favoris
run_skill_script("meal-planning", "get_user_favorites", {})

# Chercher un favori par nom
run_skill_script("meal-planning", "get_user_favorites", {"name": "poulet grillé"})

# Supprimer par nom
run_skill_script("meal-planning", "remove_favorite_recipe", {"recipe_name": "poulet grillé"})

# Supprimer par ID (retourné par get_user_favorites)
run_skill_script("meal-planning", "remove_favorite_recipe", {"favorite_id": "abc-123-uuid"})

Paramètres generate_week_plan

Param Type Défaut Description
num_days int 1 Nombre de jours (1-7). 7 uniquement si demandé
start_date str aujourd'hui (ou lundi si num_days≥7) Format YYYY-MM-DD
meals list[dict] [] Specs repas par scope. Méthode recommandée. Voir tableau ci-dessous
meal_structure str auto 3_consequent_meals (3 repas, 0 collation), 3_meals_1_preworkout (3 repas + 1 collation), 3_meals_2_snacks, 4_meals. Auto-détecté si omis (≥2500 kcal → ajoute collation)

Structure d'une entrée meals[]

Clé Type Obligatoire Description
meal_type str oui Slug : petit-dejeuner / dejeuner / diner / collation
scope str oui all (tous les jours), day (un jour précis), batch (N jours consécutifs), auto (IA pioche, équivalent à omettre l'entrée)
request str non Description du plat. Omis ou scope="auto" → la DB pioche
day str si scope="day" Jour FR (LundiDimanche, ou Demain / Aujourd'hui / Après-demain)
days int si scope="batch" Nombre de jours consécutifs (taille du block)
start str non (scope="batch" uniquement) Jour de début du block batch (défaut : jour 0 du plan)

Priorité de résolution : day > batch > all > auto. Une entrée plus spécifique remplace silencieusement une plus large.

Conflits : deux entrées explicites couvrant le même (jour, meal_type) avec des plats différents → erreur MEAL_SPEC_CONFLICT. Ex : scope="day" Mardi midi "X" + scope="batch" midi days=3 "Y" → conflit.

Annexe — Paramètres legacy (dépréciés, encore acceptés)

Encore fonctionnels en attendant la migration complète. Si le nouveau schéma meals[] est aussi fourni, le legacy est ignoré avec un warning. Préférer meals[].

Param legacy Équivalent meals[]
meal_preferences: {"petit-dejeuner": "X"} [{meal_type: "petit-dejeuner", scope: "all", request: "X"}]
custom_requests: {"Mardi": {"dejeuner": "X"}} [{meal_type: "dejeuner", scope: "day", day: "Mardi", request: "X"}]
batch_days: 3 + meal_preferences: {"dejeuner": "X"} [{meal_type: "dejeuner", scope: "batch", days: 3, request: "X"}]
notes: "Mardi risotto" [{meal_type: "dejeuner", scope: "day", day: "Mardi", request: "risotto"}]
vary_breakfast: false (avec petit-déj fixé) Implicite : scope: "all" sur petit-déjeuner

Paramètres add_favorite_recipe

Param Type Obligatoire Description
recipe_id str oui UUID de la recette (retourné par generate_custom_recipe)
notes str non Note libre sur la recette

Paramètres get_user_favorites

Param Type Obligatoire Description
name str non Filtre par nom (recherche fuzzy par mots)

Paramètres remove_favorite_recipe

Param Type Obligatoire Description
favorite_id str non* UUID du favori (retourné par get_user_favorites)
recipe_name str non* Nom de la recette (recherche fuzzy). *Au moins un des deux requis.

Paramètres generate_custom_recipe

Param Type Obligatoire Description
recipe_request str oui Description de la recette souhaitée
meal_type str oui Slug : petit-dejeuner / dejeuner / diner / collation
num_servings int non Nombre de portions (défaut 1, borné 1-12). Quantités TOTALES pour N portions ; macros stockées PAR PORTION (total / N).
ingredient_list list[str] non Ingrédients à utiliser en priorité (ex. inventaire frigo). Vide → aucune contrainte.

Conversion préférences utilisateur → meals[]

Préférence globale (tous les jours) → scope: "all"

  • "omelette le matin" → [{meal_type: "petit-dejeuner", scope: "all", request: "omelette aux oeufs"}]
  • "du poisson le soir" → [{meal_type: "diner", scope: "all", request: "plat à base de poisson"}]
  • "go" / "par défaut" → meals: [] (ou paramètre omis → défauts automatiques)

Demande pour un jour précis → scope: "day"

  • "mardi midi poulet ratatouille" → [{meal_type: "dejeuner", scope: "day", day: "Mardi", request: "poulet ratatouille"}]
  • "jeudi soir saumon grillé" → [{meal_type: "diner", scope: "day", day: "Jeudi", request: "saumon grillé"}]
  • "samedi matin pancakes" → [{meal_type: "petit-dejeuner", scope: "day", day: "Samedi", request: "pancakes protéinés"}]
  • "demain midi poulet grillé" → [{meal_type: "dejeuner", scope: "day", day: "Demain", request: "poulet grillé"}] (résolu automatiquement)

Batch cooking → scope: "batch"

  • "3 jours du même midi" (sans plat précisé) → [{meal_type: "dejeuner", scope: "batch", days: 3}]
  • "3 jours de poulet ratatouille midi" → [{meal_type: "dejeuner", scope: "batch", days: 3, request: "poulet ratatouille"}]
  • "batch cooking 3 jours midi + Mardi je veux du poulet" → [{meal_type: "dejeuner", scope: "batch", days: 3, request: "poulet"}] (le batch capture la demande de Mardi sur tout le block)

Structure repas → meal_structure

  • "3 repas sans collation" / "supprime la collation" / "juste 3 repas" → meal_structure: "3_consequent_meals"
  • "ajoute une collation pre-workout" → meal_structure: "3_meals_1_preworkout"
  • "4 repas egaux" → meal_structure: "4_meals"

Règle clé : un seul tableau meals[] exprime toutes les préférences ; chaque entrée a un scope explicite. Ne pas mélanger avec les anciens kwargs (meal_preferences, custom_requests, notes, batch_days). Clés jour : Lundi, Mardi, Mercredi, Jeudi, Vendredi, Samedi, Dimanche. Aussi accepté : Demain, Aujourd'hui, Après-demain (résolu automatiquement). Clés repas : petit-dejeuner, dejeuner, diner, collation (slugs DB, sans accents). Mots-clés repas : "matin/petit-déj" → petit-dejeuner, "midi/déjeuner" → dejeuner, "soir/dîner" → diner, "collation/goûter" → collation.

Présentation du résultat — FORMAT OBLIGATOIRE

Le script retourne un JSON avec meal_plan_id, meal_plan.days[], weekly_summary. Tu DOIS utiliser ce JSON exactement.

Étape 1 : Résumé court (3-4 lignes max)

  • Nombre de jours, calories moyennes (weekly_summary.average_calories), protéines moyennes
  • Sécurité allergènes : validation passée ✅

Étape 2 : Résumé par jour (texte simple)

Pour chaque jour, afficher un résumé compact :

Lundi (2026-03-09) — 2 964 kcal, 172g protéines

  • Petit-déjeuner : Omelette aux épinards
  • Déjeuner : Poulet grillé aux légumes
  • Dîner : Saumon teriyaki

NE PAS émettre de marqueurs <!--UI:DayPlanCard:...--> — le détail complet (ingrédients, macros, instructions) est sur la page dédiée via le lien ci-dessous.

Étape 3 : Lien plan complet — OBLIGATOIRE

Copie-colle le champ plan_link du JSON tel quel, seul sur une ligne, sans emoji ni mise en forme :

{response.plan_link}

NE PAS entourer de **bold**, 📖, ni de texte additionnel sur la même ligne. Sans ce lien, l'utilisateur ne peut pas accéder au plan ni l'ajouter en favori.

Étape 4 : QuickReplyChips

<!--UI:QuickReplyChips:{"options":[{"label":"Liste de courses","value":"generate_grocery_list"},{"label":"Régénérer le plan","value":"regenerate_plan"}]}-->

CE QUI EST INTERDIT

  • Émettre des marqueurs <!--UI:DayPlanCard:...--> — le détail est sur la page dédiée
  • Omettre le lien /plans/{meal_plan_id} — sinon pas de favori possible
  • Inventer des valeurs — tout vient du JSON retourné par le script

MealCard — OBLIGATOIRE pour toute recette

Chaque fois que tu proposes une recette (individuelle OU dans un plan), tu DOIS émettre un marqueur MealCard à la fin de ta réponse. Les scripts de recette retournent un champ ui_marker — copie-le tel quel. Sans ce marqueur, la recette n'est pas sauvegardable.

[ton texte avec instructions, ingrédients, etc.]

<!--UI:MealCard:{"meal_type":"dejeuner","recipe_name":"Poulet rôti aux herbes","calories":650,"macros":{"protein_g":52,"carbs_g":68,"fat_g":15},"prep_time":35,"ingredients":["Filet de poulet 200g","Riz complet 80g","Brocoli 150g"],"instructions":"1. Préchauffer le four à 200°C\n2. Assaisonner le poulet\n3. Cuire 25 min\n4. Cuire le riz et le brocoli en parallèle\n5. Dresser l'assiette"}-->

Sécurité allergènes

Tolérance zéro — filtrage Python automatique en 2 couches. Voir references/allergen_families.md.

Install via CLI
npx skills add https://github.com/mzt-76/AI-nutrition --skill meal-planning
Repository Details
star Stars 1
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator