feat: split photo-import into vision recognition + text generation
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
This commit is contained in:
@@ -28,19 +28,23 @@ export async function POST(req: NextRequest) {
|
||||
const userId = session!.user.id;
|
||||
const locale = (session!.user as { locale?: string }).locale ?? "en";
|
||||
|
||||
const configResult = await resolveAiConfigOrError(() => getModelConfigForUseCase(userId, "vision"));
|
||||
if (!configResult.ok) return configResult.response;
|
||||
const aiConfig = configResult.data;
|
||||
const visionConfigResult = await resolveAiConfigOrError(() => getModelConfigForUseCase(userId, "vision"));
|
||||
if (!visionConfigResult.ok) return visionConfigResult.response;
|
||||
const visionConfig = visionConfigResult.data;
|
||||
|
||||
// Fall back to vision-capable defaults if no explicit model configured
|
||||
if (!aiConfig.model) {
|
||||
if (aiConfig.provider === "openai") aiConfig.model = "gpt-4o";
|
||||
else if (aiConfig.provider === "anthropic") aiConfig.model = "claude-sonnet-4-6";
|
||||
if (!visionConfig.model) {
|
||||
if (visionConfig.provider === "openai") visionConfig.model = "gpt-4o";
|
||||
else if (visionConfig.provider === "anthropic") visionConfig.model = "claude-sonnet-4-6";
|
||||
}
|
||||
|
||||
const textConfigResult = await resolveAiConfigOrError(() => getModelConfigForUseCase(userId, "text"));
|
||||
if (!textConfigResult.ok) return textConfigResult.response;
|
||||
const textConfig = textConfigResult.data;
|
||||
|
||||
const result = await withAiQuota(userId, session!.user.tier as "free" | "pro", () =>
|
||||
importFromPhoto(parsed.data.imageBase64, parsed.data.mimeType, aiConfig, locale),
|
||||
{ skipQuota: aiConfig.isByok }
|
||||
importFromPhoto(parsed.data.imageBase64, parsed.data.mimeType, visionConfig, textConfig, locale),
|
||||
{ skipQuota: visionConfig.isByok && textConfig.isByok }
|
||||
);
|
||||
if (!result.ok) return result.response;
|
||||
const recipe = result.data;
|
||||
|
||||
Reference in New Issue
Block a user