f0340859fa
The photo-import flow used one vision-capable model to both read the photo and structure the full recipe (quantities, steps, timing) in a single call. Split it into two: a vision model recognizes what's in the picture, then a text model reconstructs the recipe from that description — same pattern the pantry photo-scan already uses for recognition, and lets structuring use whichever model is actually configured for text generation. Still counts as one AI-quota unit. v0.37.0
31 lines
1.5 KiB
TypeScript
31 lines
1.5 KiB
TypeScript
import type { AiConfig } from "../factory";
|
|
import { recognizePhoto } from "./recognize-photo";
|
|
import { generateRecipeFromRecognition, type GeneratedRecipeFromRecognition } from "./generate-recipe-from-recognition";
|
|
|
|
export type ImportedRecipe =
|
|
| { found: false; recipeType: "dish" | "drink"; title: string; ingredients: []; steps: [] }
|
|
| ({ found: true; recipeType: "dish" | "drink" } & GeneratedRecipeFromRecognition);
|
|
|
|
/** Orchestrates the two-step photo-import flow: a vision model recognizes
|
|
* what's in the photo (`recognizePhoto`), then a text model reconstructs the
|
|
* full structured recipe from that recognition (`generateRecipeFromRecognition`).
|
|
* Splitting the call lets each step use the model best suited to it — vision
|
|
* for the photo, text for structuring — instead of one model doing both. */
|
|
export async function importFromPhoto(
|
|
imageBase64: string,
|
|
mimeType: "image/jpeg" | "image/png" | "image/webp",
|
|
visionConfig: AiConfig | undefined,
|
|
textConfig: AiConfig | undefined,
|
|
locale?: string,
|
|
): Promise<ImportedRecipe> {
|
|
const recognition = await recognizePhoto(imageBase64, mimeType, visionConfig);
|
|
|
|
if (!recognition.found) {
|
|
return { found: false, recipeType: recognition.recipeType, title: recognition.title, ingredients: [], steps: [] };
|
|
}
|
|
|
|
const generated = await generateRecipeFromRecognition(recognition, { ...textConfig, language: locale ?? "en" });
|
|
|
|
return { found: true, recipeType: recognition.recipeType, ...generated };
|
|
}
|