5ab2acc711
- Fix Authentik button type casting issue in login page * Use exported signIn instead of authClient type assertion * Add proper error handling for OAuth calls - Fix image MIME type handling in import-photo.ts * Convert base64 to data URL format for AI SDK compatibility - Fix type annotations in auth/server.ts changeEmail handler * Add explicit type annotation for destructured parameters These TypeScript errors were preventing 'pnpm build' from completing during Docker image build process.
64 lines
1.9 KiB
TypeScript
64 lines
1.9 KiB
TypeScript
import { generateObject } from "ai";
|
|
import { z } from "zod";
|
|
import { resolveModel, type AiConfig } from "../factory";
|
|
|
|
const ImportedRecipeSchema = z.object({
|
|
title: z.string(),
|
|
description: z.string().optional(),
|
|
baseServings: z.number().int().min(1).optional(),
|
|
prepMins: z.number().int().min(0).optional(),
|
|
cookMins: z.number().int().min(0).optional(),
|
|
difficulty: z.enum(["easy", "medium", "hard"]).optional(),
|
|
dietaryTags: z.object({
|
|
vegan: z.boolean().optional(),
|
|
vegetarian: z.boolean().optional(),
|
|
glutenFree: z.boolean().optional(),
|
|
dairyFree: z.boolean().optional(),
|
|
nutFree: z.boolean().optional(),
|
|
halal: z.boolean().optional(),
|
|
kosher: z.boolean().optional(),
|
|
}).optional(),
|
|
ingredients: z.array(z.object({
|
|
rawName: z.string(),
|
|
quantity: z.string().optional(),
|
|
unit: z.string().optional(),
|
|
note: z.string().optional(),
|
|
})),
|
|
steps: z.array(z.object({
|
|
instruction: z.string(),
|
|
timerSeconds: z.number().int().optional(),
|
|
})),
|
|
});
|
|
|
|
export type ImportedRecipe = z.infer<typeof ImportedRecipeSchema>;
|
|
|
|
export async function importFromPhoto(
|
|
imageBase64: string,
|
|
mimeType: "image/jpeg" | "image/png" | "image/webp",
|
|
config?: AiConfig,
|
|
_locale?: string,
|
|
): Promise<ImportedRecipe> {
|
|
const model = resolveModel(config);
|
|
|
|
// Create a data URL from base64
|
|
const imageDataUrl = `data:${mimeType};base64,${imageBase64}`;
|
|
|
|
const { object } = await generateObject({
|
|
model,
|
|
schema: ImportedRecipeSchema,
|
|
system:
|
|
"You are a recipe extraction specialist. Extract the complete recipe from the provided image. Be precise with ingredient quantities and cooking instructions.",
|
|
messages: [
|
|
{
|
|
role: "user",
|
|
content: [
|
|
{ type: "image", image: imageDataUrl },
|
|
{ type: "text", text: "Extract the complete recipe from this image." },
|
|
],
|
|
},
|
|
],
|
|
});
|
|
|
|
return object;
|
|
}
|