fix(recipe-generation): robustare Gemini-enheter, butter-densitet, utökad pilot-output

This commit is contained in:
Sven (AAMOS AI)
2026-08-09 20:45:59 +07:00
parent 1f746dc822
commit e4efb150aa
3 changed files with 23 additions and 2 deletions
+9 -1
View File
@@ -362,6 +362,14 @@ export class GeminiAamosClient implements AamosClient {
const costUsd = this.estimateCostUsd(inputTokens, outputTokens); const costUsd = this.estimateCostUsd(inputTokens, outputTokens);
await this.recordSpend(costUsd); await this.recordSpend(costUsd);
// Normalisera enheter defensivt: Gemini kan ibland returnera "dl"/"msk"/"st".
for (const c of parsed.candidates) {
for (const ing of c.ingredients) {
const normalized = normalizeUnit(String(ing.unit));
if (normalized) ing.unit = normalized as typeof ing.unit;
}
}
const latencyMs = Date.now() - started; const latencyMs = Date.now() - started;
return { return {
@@ -411,7 +419,7 @@ Begränsningar:
Regler: Regler:
- Recepten ska vara realistiska vardagsrätter för svenska hushåll. - Recepten ska vara realistiska vardagsrätter för svenska hushåll.
- Stegen ska vara tydliga, med rimliga tider och temperaturer. - Stegen ska vara tydliga, med rimliga tider och temperaturer.
- Använd svenska mått (g, dl, msk, tsk, st). - Använd ENDAST dessa exakta enhetskoder: GRAM, KILOGRAM, MILLILITER, DECILITER, LITER, TEASPOON, TABLESPOON, CUP_US, COUNT, PORTION, PINCH, SLICE, CLOVE, CAN, PACKAGE. Aldrig "g", "dl", "msk", "tsk", "st".
- Formuleringen ska vara mjölkprincips-vänlig: ingen svinnskam, inget "släng". - Formuleringen ska vara mjölkprincips-vänlig: ingen svinnskam, inget "släng".
- Varje ingrediens MÅSTE finnas i katalogen ovan. - Varje ingrediens MÅSTE finnas i katalogen ovan.
- Svara ENDAST med giltig JSON i exakt detta format: - Svara ENDAST med giltig JSON i exakt detta format:
@@ -207,6 +207,7 @@ export const SEED_INGREDIENTS: SeedIngredient[] = [
...vgt, ...vgt,
allergens: ["milk"], allergens: ["milk"],
containsLactose: true, containsLactose: true,
densityGPerMl: 0.91,
n: { kcal: 744, p: 0.6, k: 0.7, f: 82, mf: 52, salt: 1.2 }, n: { kcal: 744, p: 0.6, k: 0.7, f: 82, mf: 52, salt: 1.2 },
shelfLifeGuidance: { fridge: 60 }, shelfLifeGuidance: { fridge: 60 },
defaultPriceMinorPerKg: 11000, defaultPriceMinorPerKg: 11000,
@@ -110,11 +110,23 @@ async function main() {
rejectedCount: result.rejectedCount, rejectedCount: result.rejectedCount,
candidates: result.verificationResults.map((r) => ({ candidates: result.verificationResults.map((r) => ({
title: r.candidate.titleSv, title: r.candidate.titleSv,
descriptionSv: r.candidate.descriptionSv,
status: r.status, status: r.status,
reasons: r.reasons, reasons: r.reasons,
allergens: r.allergens, allergens: r.allergens,
nutritionPerPortion: r.nutritionPerPortion, nutritionPerPortion: r.nutritionPerPortion,
ingredients: r.candidate.ingredients.map((i) => i.canonicalIngredientId), ingredients: r.candidate.ingredients.map((i) => ({
id: i.canonicalIngredientId,
name: i.displayNameSv,
quantity: i.quantity,
unit: i.unit,
optional: i.optional,
})),
steps: r.candidate.steps.map((s, idx) => ({
number: idx + 1,
instruction: s.instructionSv,
durationMinutes: s.durationMinutes ?? null,
})),
})), })),
}; };