RECIPE SAVE:
intent=create/save recipe not eaten -> save_as_recipe=true, recipe_only=true
intent=log eaten meal + save recipe -> save_as_recipe=true, recipe_only=false/omit
recipe_only=true -> food_log_write=false; save_as_recipe must be true
recipe_only=true -> recipe_title=<name>
recipe_only=true -> recipe_servings=<whole-batch servings; default 1>
recipe_only=true -> food_items=<WHOLE-BATCH ingredients with amounts>
recipe_only=true -> calories/protein_g/fat_g/carbs_g=<WHOLE-BATCH totals; estimate, never ask>
recipe_only=true -> estimate=<WHOLE-BATCH compact nutrient estimate when available>
Log a meal to the user's food diary. use: logging request or concrete meal consumed. question/habit/hypothetical alone: no write.
INFER:
- date: today, or from context ("yesterday", "last night"). For an attached meal photo with <photo_capture_times>, use that photo's local date unless the user explicitly states a different date.
- meal_time: for an attached meal photo with <photo_capture_times>, send that photo's local HH:MM unless the user explicitly states a different time/date. User-stated timing always wins. Otherwise omit unless the user gave a real clock time.
- meal_type: when meal_time is supplied, OMIT meal_type unless the user's wording explicitly names or clearly anchors a category; the server assigns the category from meal_time. Without meal_time, for a current-day plain meal/food log omit meal_type and let the server assign it from the user's resolved local clock (00:00-04:00 Snack, 04:00-10:30 Breakfast, 10:30-15:00 Lunch, 15:00-17:00 Snack, 17:00-21:30 Dinner, 21:30-24:00 Snack). Send meal_type when the user's wording explicitly names or clearly anchors a category ("breakfast", "for lunch", "post-workout shake"), or when backdating and neither capture time nor another honest clock signal exists.
MACRO SOURCE: strongest evidence wins. Never replace known stored macros with a fresh estimate.
1. REPEATS (unless a saved recipe is clearly invoked): if the user refers to a previously logged item ("same", "another", "more", "again", or equivalent in any language), OR names a food plausibly matching a recent log even without a repeat keyword (e.g. "two eggs"), call list_meals for the referenced/recent date range BEFORE estimating. If one row unambiguously matches, reuse its stored calories/protein_g/fat_g/carbs_g/alcohol_g and scale by the quantity ratio when the row's quantity is known. If the match or quantity is ambiguous, ask instead of re-estimating. If nothing matches, continue below.
2. SAVED RECIPES: referenced or selected? YES -> ALWAYS pass recipe_name (saved title) and recipe_multiplier (0.5 for half). Use stored recipe nutrition x portion deterministically; estimate only missing values or added_food_items, and sum additions with the recipe portion. NEVER log a referenced recipe as a generic food_items estimate.
3. BRAND NAMES: for a branded, restaurant, or specific product, use published macros for the stated size/variant before a generic estimate.
4. Otherwise estimate every macro from the food description. Never ask the user for macros.
MACROS: final stored meal must contain calories, protein_g, fat_g and carbs_g. recipe_name supplies stored core values; estimate and pass only missing core values or explicit changes. Without a recipe, pass food_items and those four. No partial core macros or placeholders. Saturated fat and fiber are expanded nutrients, never required for log_meal. Pass saturated_fat_g/fiber_g only when already known from strong evidence; otherwise omit them. When expanded nutrient tracking is enabled, the gated nutrient estimator can fill them; when disabled they remain unset. 0 is a real value only when the food truly contains none of that nutrient. Ask only if food_items are absent and no recipe_name applies.
FASTING: if the user ate nothing / fasted all day, log one "Fast day" Snack with every macro 0.
ESTIMATE: pass a compact 3-line block estimating every one of the app's 44 tracked nutrients for the food, in exactly this format, no prose before or after:
items:<food name>:<estimated grams>|<food name>:<estimated grams>|...
macros:<calories>;<protein_g>;<carbs_g>;<fat_g>;<alcohol_g>
nutrients:1:<value>;2:<value>;...;44:<value>
Estimate all 44 nutrients. Always return all 44 IDs. Never omit one because you are uncertain -- use your best reasonable estimate from the likely food, quantity, ingredients, preparation and comparable foods; 0 only when a nutrient is reasonably expected to be negligible. Which id is which nutrient, and its unit, is the dictionary on the estimate param.
Omit for an unchanged saved recipe; with added_food_items, estimate that addition only. Otherwise supply when available; the server estimates missing values.
DUPLICATES: if this tool returns a duplicate error, tell the user what's already logged and ask whether this is a separate serving (retry with force=true) or should update the existing entry instead (update_meal with adjusted values).
DRINKS / HYDRATION: this is the single write path for consumed drinks too. Known or reasonably inferable drink volume (tea, coffee, milk, juice, shakes, smoothies, etc.) → always report fluids, even if also contributes calories/macros/alcohol. Food moisture → omit. The server decides whether hydration tracking is enabled; never use a separate hydration write tool. A plain fluid-only intake may omit food_items and macros and send only fluids. For alcoholic drinks, include that drink's alcohol_g in its fluid item; if there is exactly one drink, the top-level alcohol_g can stand in.
CAFFEINE / DRINKS: this is the single assistant write path for caffeine too. Drinks only; exclude food moisture. When the user consumed a drink and its volume is known or reasonably inferable, include it in fluids so hydration is recorded; if the drink is caffeinated, include caffeine in the same call too. Do not leave a known-volume drink only in food_items. Each caffeine item needs caffeine_mg and may optionally include source_type. The date comes from the intake date. Preserve exact user-provided milligrams; for vague coffee/tea/energy-drink/pre-workout descriptions, estimate caffeine with the same nutrition-estimation judgment used for meal macros. Never use separate hydration or caffeine write tools. A drink-only or caffeine-only intake may omit food_items/macros.