feat: implement AI custom tag proposals

- AI now suggests dominant notes not in the system list (Part 3: Custom Suggestions)
- Updated TagSelector to show 'Neu anlegen?' buttons for AI-proposed custom tags
- Added suggested_custom_tags to bottles table and metadata schema
- Updated TastingNoteForm to handle both system and custom AI suggestions
This commit is contained in:
2025-12-19 13:20:13 +01:00
parent b2a1d292da
commit 74916aec73
12 changed files with 216 additions and 29 deletions

View File

@@ -12,12 +12,24 @@ export const geminiModel = genAI.getGenerativeModel({
});
export const SYSTEM_INSTRUCTION = `
You are a sommelier and database clerk. Analyze the whisky bottle image. Extract precise metadata.
If the image is NOT a whisky bottle or if you are very unsure, set "is_whisky" to false and provide a low "confidence" score.
You are a sommelier and database clerk. Analyze the whisky bottle image.
PART 1: METADATA EXTRACTION
Extract precise metadata. If the image is NOT a whisky bottle or if you are very unsure, set "is_whisky" to false and provide a low "confidence" score.
If a value is not visible, use null.
Infer the 'Category' (e.g., Islay Single Malt) based on the Distillery if possible.
Search specifically for a "Whiskybase ID" or "WB ID" on the label.
Output raw JSON matching the following schema:
Search specifically for a "Whiskybase ID" or "WB ID" on the label.
PART 2: SENSORY ANALYSIS (AUTO-FILL)
Based on the identified bottle, select the most appropriate flavor tags.
CONSTRAINT: You must ONLY select tags from the following provided list. Do NOT invent new tags in this field.
LIST: {AVAILABLE_TAGS}
PART 3: CUSTOM SUGGESTIONS
If you recognize highly dominant notes that are NOT in the list above, provide them in 'suggested_custom_tags'.
Limit this to 1-2 very unique notes (e.g. "Marshmallow" or "Balsamico"). Do not repeat tags from the system list.
Output strictly raw JSON matching the following schema:
{
"name": string | null,
"distillery": string | null,
@@ -27,10 +39,12 @@ Output raw JSON matching the following schema:
"vintage": string | null,
"bottleCode": string | null,
"whiskybaseId": string | null,
"distilled_at": string | null (e.g. "2010" or "12.05.2010"),
"bottled_at": string | null (e.g. "2022" or "15.11.2022"),
"batch_info": string | null (e.g. "Batch 1" or "L12.03.2022"),
"distilled_at": string | null,
"bottled_at": string | null,
"batch_info": string | null,
"is_whisky": boolean,
"confidence": number (0-100)
"confidence": number (0-100),
"suggested_tags": string[] (from provided list),
"suggested_custom_tags": string[] (new unique notes)
}
`;