smithery/ddarmon

multiperiod

Per-meal optimization for balanced meals.

Installation

$ npx skills add smithery/ddarmon --skill multiperiod

Summary

  • Per-meal optimization for balanced meals.
  • Use when user wants to control calories per meal, avoid huge snacks, balance breakfast/lunch/dinner, or needs per-meal protein targets.
  • Triggers on "per meal", "meal-by-meal", "balanced meals", "snack limits", "breakfast protein", "lunch calories".
More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 7,517 B
  • docs SUMMARY.md 309 B

History

  1. First recorded snapshot · 0 installs

SKILL.md

Multi-Period Meal Optimization

This skill creates meal plans with per-meal constraints, ensuring balanced distribution of calories and nutrients across breakfast, lunch, dinner, and snacks. This prevents issues like 995-calorie "snacks" that occur with post-hoc meal allocation.

Template-Based vs Multi-Period

Consider template-based first (--template --pattern X):

  • Produces more realistic meals (1 protein + 1 legume + vegetables per meal)
  • Different foods at each meal by design
  • Simpler to use: uv run llmn optimize --pattern pescatarian --template --json

Use multi-period when:

  • You need exact per-meal calorie/protein control (e.g., "exactly 500-550 kcal at breakfast")
  • You want to restrict specific foods to specific meals (e.g., "almonds only as snack")
  • You need equi-calorie constraints (e.g., "lunch within 100 kcal of dinner")
  • Template-based doesn't meet your specific nutrient requirements

When to Use Multi-Period

Use multi-period optimization when:

  • User wants exact calorie limits per meal (template gives approximate)
  • User needs protein targets at each meal (e.g., 30g+ at breakfast)
  • User wants lunch and dinner to be similar in calories (equi-calorie)
  • User wants to restrict certain foods to certain meals (eggs→breakfast)

Quick Start

For basic multi-period optimization with auto-derived meal targets:

uv run llmn optimize --multiperiod --json

This uses default splits: Breakfast 25%, Lunch 35%, Dinner 35%, Snack 5%.

Workflow

Step 1: Gather Daily Targets

First, get the user's overall daily targets:

  • Total daily calories (min/max)
  • Total daily protein minimum
  • Any other daily nutrient constraints

Step 2: Define Per-Meal Targets

Ask the user about meal distribution. Offer these presets:

Balanced (default):

  • Breakfast: 25% of calories
  • Lunch: 35% of calories
  • Dinner: 35% of calories
  • Snack: 5% of calories (~100-150 kcal)

Front-loaded (big breakfast):

  • Breakfast: 35% of calories
  • Lunch: 30% of calories
  • Dinner: 30% of calories
  • Snack: 5% of calories

Back-loaded (big dinner):

  • Breakfast: 20% of calories
  • Lunch: 30% of calories
  • Dinner: 45% of calories
  • Snack: 5% of calories

For a 2000 kcal diet with "Balanced" split:

  • Breakfast: 450-550 kcal
  • Lunch: 650-750 kcal
  • Dinner: 650-750 kcal
  • Snack: 50-150 kcal

Step 3: Per-Meal Protein (Optional)

Ask if user wants per-meal protein targets:

  • Breakfast protein minimum (suggest 25-30g)
  • Lunch protein minimum (suggest 40-50g)
  • Dinner protein minimum (suggest 40-50g)
  • Snack protein (usually 5-10g)

Step 4: Create Multi-Period Profile

Create a YAML profile at /tmp/multiperiod_profile.yaml:

name: multiperiod_custom
description: "Multi-period optimization with per-meal constraints"

# Daily totals (linking constraints)
calories:
  min: <daily_cal_min>
  max: <daily_cal_max>

nutrients:
  protein:
    min: <daily_protein_min>
  fiber:
    min: 30

# Per-meal structure (triggers multi-period mode)
meals:
  breakfast:
    calories:
      min: <breakfast_cal_min>
      max: <breakfast_cal_max>
    nutrients:
      protein:
        min: <breakfast_protein_min>

  lunch:
    calories:
      min: <lunch_cal_min>
      max: <lunch_cal_max>
    nutrients:
      protein:
        min: <lunch_protein_min>

  dinner:
    calories:
      min: <dinner_cal_min>
      max: <dinner_cal_max>
    nutrients:
      protein:
        min: <dinner_protein_min>

  snack:
    calories:
      min: 50
      max: 200  # Keep snacks small!

include_tags:
  - staple

options:
  max_grams_per_food: 400

Step 5: Add Optional Constraints

Equi-calorie constraint (lunch ≈ dinner):

equicalorie:
  - meals: [lunch, dinner]
    tolerance: 100  # Within 100 kcal of each other

Food-meal affinity (restrict foods to specific meals):

food_meal_rules:
  171287: [breakfast]     # Eggs only at breakfast
  170567: [snack]         # Almonds only as snack
  175167: [lunch, dinner] # Salmon for lunch/dinner only

Step 6: Run Optimization

uv run llmn optimize --file /tmp/multiperiod_profile.yaml --json

Step 7: Present Results

The JSON output has a meals structure:

{
  "data": {
    "meals": [
      {
        "meal_type": "breakfast",
        "foods": [...],
        "total_calories": 480,
        "total_protein": 32
      },
      {
        "meal_type": "snack",
        "foods": [...],
        "total_calories": 145,  // Now properly constrained!
        "total_protein": 5
      }
    ],
    "daily_totals": {...}
  }
}

Present each meal separately with its foods and totals.

Step 8: Handle Infeasibility

Multi-period has more constraints, so infeasibility is more common. Check for:

  1. Per-meal minimums exceed daily maximum:

"Your per-meal calorie minimums sum to 2500 kcal but daily max is 2000 kcal" → Reduce per-meal minimums

  1. Per-meal maximums below daily minimum:

"Your per-meal calorie maximums sum to 1500 kcal but daily min is 1800 kcal" → Increase per-meal maximums

  1. Protein constraints too tight:

"Can't get 50g protein at breakfast with available foods" → Reduce breakfast protein or add high-protein breakfast foods

The optimizer's infeasibility_diagnosis field explains the conflict.

Example Profiles

Weight Loss with Balanced Meals (1800 kcal)

calories:
  min: 1700
  max: 1900

nutrients:
  protein:
    min: 150

meals:
  breakfast:
    calories: {min: 400, max: 500}
    nutrients: {protein: {min: 30}}
  lunch:
    calories: {min: 550, max: 650}
    nutrients: {protein: {min: 45}}
  dinner:
    calories: {min: 550, max: 650}
    nutrients: {protein: {min: 45}}
  snack:
    calories: {min: 50, max: 150}

equicalorie:
  - meals: [lunch, dinner]
    tolerance: 75

High-Protein Muscle Building (2800 kcal)

calories:
  min: 2700
  max: 2900

nutrients:
  protein:
    min: 200

meals:
  breakfast:
    calories: {min: 600, max: 750}
    nutrients: {protein: {min: 50}}
  lunch:
    calories: {min: 800, max: 950}
    nutrients: {protein: {min: 60}}
  dinner:
    calories: {min: 800, max: 950}
    nutrients: {protein: {min: 60}}
  snack:
    calories: {min: 200, max: 350}
    nutrients: {protein: {min: 20}}

Commands Reference

# Quick multi-period with auto-derived targets
uv run llmn optimize --multiperiod --json

# Multi-period with custom profile
uv run llmn optimize --file /tmp/multiperiod_profile.yaml --json

# With verbose output (shows constraint matrices)
uv run llmn optimize --file /tmp/multiperiod_profile.yaml --verbose

# With explicit food IDs (bypass tag filtering)
uv run llmn optimize --multiperiod --foods 175167,171287,172421 --json

Tips

  1. Start simple: Use --multiperiod flag first, then customize with a profile
  2. Check the math: Per-meal calorie ranges must sum to cover daily range
  3. Read the diagnosis: Infeasibility messages are specific and actionable
  4. Snacks are small: Keep snack max at 150-200 kcal to avoid the "995 cal snack" problem
  5. Equi-calorie helps: Requiring lunch ≈ dinner creates more balanced days