import { generateObject } from "ai"; import { z } from "zod"; import { resolveModel, type AiConfig } from "../factory"; const TranslationOutputSchema = z.object({ title: z.string(), description: z.string(), ingredients: z.array(z.object({ rawName: z.string().describe("Translated ingredient name only — never add the quantity or unit, those are handled separately and unaffected by translation."), note: z.string().optional(), })), steps: z.array(z.object({ instruction: z.string(), })), }); export type TranslatedRecipe = z.infer; export async function translateRecipe( recipe: { title: string; description?: string | null; ingredients: Array<{ rawName: string; note?: string | null }>; steps: Array<{ instruction: string }>; }, targetLanguage: string, config?: AiConfig ): Promise { const model = resolveModel(config); const { object } = await generateObject({ model, schema: TranslationOutputSchema, system: "You are a professional culinary translator. Translate recipes accurately, preserving culinary meaning, cooking terms, and cultural context. Keep ingredient quantities and units as-is (numbers and unit abbreviations are universal). Only translate text content.", prompt: `Translate the following recipe into ${targetLanguage}. Return the same structure with translated text.\n\nTitle: ${recipe.title}\nDescription: ${recipe.description ?? ""}\nIngredients: ${recipe.ingredients.map((i) => `- ${i.rawName}${i.note ? ` (${i.note})` : ""}`).join("\n")}\nSteps: ${recipe.steps.map((s, i) => `${i + 1}. ${s.instruction}`).join("\n")}`, }); return object; }