feat: auto-classify AI recipes as dish/drink (v0.33.0)

generate, generate-from-idea, URL import, and photo import all now
have the AI set recipeType directly (defaulting to "dish" whenever
ambiguous, per instruction), with cookMins force-cleared for drinks
as a backstop in case the model doesn't follow the prompt guidance.
1-serving-by-default for unspecified drink quantities is left to the
model's own judgment of the request text, since there's no reliable
way to detect "was a serving count stated" without re-parsing intent.

Drink recipes get a distinct default icon (no cover photo case), and
Explore gains the same dish/drink Type filter My Recipes already had.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Arnaud
2026-07-14 15:17:33 +02:00
parent 3042d289a0
commit af92b8cc71
16 changed files with 80 additions and 17 deletions
+9 -1
View File
@@ -4,6 +4,7 @@ import { resolveModel, type AiConfig } from "../factory";
import { dietaryTagsSchema, ingredientSchema, stepSchema } from "./recipe-schema";
const RecipeOutputSchema = z.object({
recipeType: z.enum(["dish", "drink"]).describe("\"drink\" only for a beverage/cocktail (no cooking step) — \"dish\" for anything else, including if unsure."),
title: z.string(),
description: z.string(),
baseServings: z.number().int().min(1).max(100),
@@ -31,9 +32,16 @@ export async function generateRecipe(
model,
schema: RecipeOutputSchema,
system:
`You are a professional chef and culinary writer. Generate detailed, accurate, and delicious recipes. For ingredients: quantity must be a number only (e.g. 0.25, 1.5, 2), unit is a separate string (e.g. 'cup', 'tbsp', 'g', 'ml'). Never combine quantity and unit into one string. Include helpful notes for ingredients when relevant.${langInstruction}${difficultyInstruction}${userInstruction}`,
`You are a professional chef and culinary writer. Generate detailed, accurate, and delicious recipes. For ingredients: quantity must be a number only (e.g. 0.25, 1.5, 2), unit is a separate string (e.g. 'cup', 'tbsp', 'g', 'ml'). Never combine quantity and unit into one string. Include helpful notes for ingredients when relevant. Set recipeType to "drink" only for a beverage/cocktail with no cooking involved (mixing, shaking, stirring, blending) — default to "dish" whenever it's ambiguous. For a drink, never set cookMins, and default baseServings to 1 unless the request specifically asks for more than one serving/portion.${langInstruction}${difficultyInstruction}${userInstruction}`,
prompt: `Create a recipe for: ${prompt}`,
});
// Belt-and-suspenders in case the model doesn't follow the drink-specific
// instructions above — a drink has no "cook" step by definition, and a
// model that ignores the 1-serving-by-default guidance would otherwise
// silently produce a batch-sized drink recipe.
if (object.recipeType === "drink") {
return { ...object, cookMins: undefined };
}
return object;
}