62 lines
2.6 KiB
JavaScript
62 lines
2.6 KiB
JavaScript
// JSON schema handed to `output_config.format`, so the answer is guaranteed to
|
|
// parse. The descriptions repeat the hard rules: the schema travels with every
|
|
// request, and a field description is read right where the model fills it in.
|
|
// Structured outputs require `additionalProperties: false` on every object and
|
|
// accept no numeric or string constraints - nullability is expressed with
|
|
// `anyOf`.
|
|
export const RECIPE_SCHEMA = {
|
|
type: 'object',
|
|
properties: {
|
|
name: {
|
|
type: 'string',
|
|
description: 'Title of the recipe, as written in the document.'
|
|
},
|
|
recipeYield: {
|
|
anyOf: [{ type: 'string' }, { type: 'null' }],
|
|
description: 'Yield as written, for example "4 personnes". null when the document does not state one.'
|
|
},
|
|
recipeIngredient: {
|
|
type: 'array',
|
|
items: { type: 'string' },
|
|
description: 'One entry per ingredient line, EXACTLY as written in the document: not reworded, not corrected, not converted. This is the text that gets printed.'
|
|
},
|
|
parsedIngredients: {
|
|
type: 'array',
|
|
description: 'The same lines split up, only so a shopping list can be added up and search can work. Same order and same count as recipeIngredient.',
|
|
items: {
|
|
type: 'object',
|
|
properties: {
|
|
raw: {
|
|
type: 'string',
|
|
description: 'Character for character identical to recipeIngredient at the same index.'
|
|
},
|
|
name: {
|
|
type: 'string',
|
|
description: 'The ingredient alone, without quantity, unit or preparation.'
|
|
},
|
|
quantity: {
|
|
anyOf: [{ type: 'number' }, { type: 'null' }],
|
|
description: 'Number stated on the line, or null. Never a number the document does not state, and never a conversion of "une poignée" or "un filet" into grams.'
|
|
},
|
|
unit: {
|
|
anyOf: [{ type: 'string' }, { type: 'null' }],
|
|
description: 'Unit as written, including imprecise ones such as "poignée", "filet", "pincée". null when the line states none.'
|
|
},
|
|
imprecise: {
|
|
type: 'boolean',
|
|
description: 'true when the line gives no measurable amount ("une poignée", "un filet", "au goût", "quelques").'
|
|
}
|
|
},
|
|
required: ['raw', 'name', 'quantity', 'unit', 'imprecise'],
|
|
additionalProperties: false
|
|
}
|
|
},
|
|
recipeInstructions: {
|
|
type: 'array',
|
|
items: { type: 'string' },
|
|
description: 'One entry per step, as written in the document.'
|
|
}
|
|
},
|
|
required: ['name', 'recipeYield', 'recipeIngredient', 'parsedIngredients', 'recipeInstructions'],
|
|
additionalProperties: false
|
|
}
|