Tofu/scripts/import-recipes/extraction/extractRecipe.js
2026-09-18 01:41:02 +02:00

31 lines
1.4 KiB
JavaScript

import { MODEL_ID } from '#import-recipes/extraction/MODEL_ID.js'
import { RECIPE_SCHEMA } from '#import-recipes/extraction/RECIPE_SCHEMA.js'
import { buildExtractionPrompt } from '#import-recipes/extraction/buildExtractionPrompt.js'
import { readRecipeResponse } from '#import-recipes/extraction/readRecipeResponse.js'
const MAX_TOKENS = 16000
// The only call to the model in this tool. It never throws: a failure comes back
// as { ok: false, reason } so the CLI can log it and carry on with the next file.
//
// `output_config.format` pins the answer to RECIPE_SCHEMA - no prefill, no
// "answer with JSON only" wishful thinking. Thinking is adaptive, which is the
// default on this model; it is stated because splitting an ingredient list
// without inventing numbers is exactly the kind of thing worth thinking about.
export async function extractRecipe({ client, fileName, paragraphs }) {
try {
const response = await client.messages.create({
model: MODEL_ID,
max_tokens: MAX_TOKENS,
thinking: { type: 'adaptive' },
output_config: { format: { type: 'json_schema', schema: RECIPE_SCHEMA } },
messages: [
{ role: 'user', content: buildExtractionPrompt({ fileName, paragraphs }) }
]
})
const result = readRecipeResponse(response)
return result.ok ? { ok: true, recipe: result.recipe, usage: response.usage } : result
} catch (error) {
return { ok: false, reason: error.message }
}
}