""" Prompts for the two-pass pipeline. Pass 1: Identify ingredients from image/text. Pass 2: Analyze health impacts (with or without API data). """ IDENTIFY_PROMPT = """\ Look at this image of food or a food product label and list the ACTUAL FOOD INGREDIENTS in English. CRITICAL RULES: 1. TRANSLATE everything to English. No German, French, Dutch, or any other language in your output. 2. List only ACTUAL FOOD ITEMS (sugar, hazelnut, milk, cocoa butter, etc.) 3. Do NOT include words like "ingredients", "contains", "may contain", "allergens", "nutrition facts", section headers, or packaging text. 4. Do NOT repeat items. 5. For percentages like "hazelnut (10%)", just write "hazelnut". 6. Output ONLY a JSON array of English ingredient names, nothing else. Example input: German label saying "Zutaten: Zucker, Haselnüsse, Magermilchpulver" Example output: ["sugar", "hazelnuts", "skim milk powder"] You may reason through the label first if that helps you read it correctly, but do it ONCE and briefly - don't redraft or re-check multiple times. When you are ready to give your final answer, output the exact line @@@INGREDIENTS_START@@@ then the JSON array on its own, then the exact line @@@INGREDIENTS_END@@@ Put nothing else between those two marker lines.\ """ HEALTH_GOALS = { "General": "Provide a balanced overview of all health aspects.", "Heart health": "Focus on cardiovascular health: sodium, potassium, fiber, saturated fat, omega-3s.", "Anti-inflammatory": "Focus on inflammation: antioxidants, omega-3/6 ratio, polyphenols.", "Blood sugar": "Focus on glycemic impact: fiber, sugars, glycemic index, insulin sensitivity.", "Gut health": "Focus on digestive health: fiber types, prebiotics, fermented ingredients.", "Energy": "Focus on sustained energy: complex carbs, B vitamins, iron, protein quality.", "Bone health": "Focus on skeletal health: calcium, vitamin D, vitamin K, magnesium.", } AUDIENCES = { "Everyone": ( "You are a helpful nutrition guide explaining food to someone who is not " "a health expert. Imagine you are explaining to a regular person who just " "wants to understand what they are eating and how it affects their body.\n\n" "TONE RULES:\n" "- Use clear, everyday language. Avoid medical jargon.\n" "- If you must use a technical term, explain it simply in parentheses.\n" "- Keep sentences short and easy to follow.\n" "- When a study is available, mention it naturally like 'Research shows " "that...' and add [Author Year] for the reference.\n" ), "Science / Biomedical": ( "You are a nutrition scientist writing for readers with a biomedical or " "life sciences background. They understand biochemistry, metabolic pathways, " "and can read study references directly.\n\n" "TONE RULES:\n" "- Use precise scientific terminology freely (no need to simplify).\n" "- Reference specific metabolic pathways, bioactive compounds, and mechanisms " "of action where the data supports it.\n" "- Cite studies formally as [Author Year] and note study type (RCT, meta-analysis, " "in vitro, animal model) so the reader can judge evidence quality.\n" "- Distinguish between established mechanisms and preliminary/associative findings.\n" ), } def build_analysis_prompt(ingredients_data: dict, literature_data: dict, health_goal: str = "General", audience: str = "Everyone", nutrition_failures: int = 0, literature_failures: int = 0) -> str: """Build the analysis prompt, adapting to available data and audience.""" goal_instruction = HEALTH_GOALS.get(health_goal, HEALTH_GOALS["General"]) # Determine data availability has_nutrition = any(v is not None for v in ingredients_data.values()) has_literature = any(len(v) > 0 for v in literature_data.values()) data_note = "" if nutrition_failures > 0 or literature_failures > 0: data_note = ( "\nNOTE: Some database lookups failed (rate limiting). " "For ingredients without database data, use your own knowledge " "but clearly mark those sections with '(based on general knowledge)' " "so the user knows it is not from the database.\n" ) # Build per-ingredient data sections sections = [] for ingredient in ingredients_data: s = f"\n### {ingredient}\n" nutrition = ingredients_data[ingredient] if nutrition is not None: s += f"USDA match: {nutrition['matched_food']}\n" s += "Nutrients per 100g:\n" for name, val in nutrition["nutrients"].items(): s += f" {name}: {val}\n" else: s += "No USDA data available. Use your knowledge.\n" papers = literature_data.get(ingredient, []) if papers: s += f"\nStudies ({len(papers)}):\n" for i, p in enumerate(papers, 1): s += f" [{i}] {p.get('title', 'Untitled')}\n" s += f" {p.get('authors', '')}, {p.get('journal', '')} {p.get('year', '')}\n" if p.get("abstract"): s += f" Abstract: {p['abstract'][:300]}...\n" sections.append(s) audience_instruction = AUDIENCES.get(audience, AUDIENCES["Everyone"]) prompt = f"""\ {audience_instruction} IMPORTANT RULES: - Cover ALL ingredients provided, not just some of them. - Be balanced: always mention both good and not-so-good aspects. - Be honest about what science knows well vs. what is still uncertain. - Do NOT invent studies or nutritional values. Only use what is provided. - Keep each ingredient section concise (4-6 bullet points total). Health focus: {goal_instruction} {data_note} Structure your response EXACTLY like this: ## What's on your plate Write 2-3 sentences summarizing the overall nutritional picture. Is this generally a healthy choice? What stands out most? Then for EACH ingredient, write a section: ### Ingredient name **Good stuff:** - One benefit per bullet point - Cite studies where available [Author Year] **Watch out:** - One concern per bullet point - Be specific and practical **In this meal:** One sentence about how this ingredient interacts with the others. After covering ALL ingredients, end with: ## Tips - Tip 1 - Tip 2 - Tip 3 HOW TO THINK ABOUT THIS: Weighing the science is genuinely useful here, so do reason about each ingredient - but do it ONCE, briefly (a few sentences per ingredient is plenty), and then move straight to writing the final report. Do NOT redraft, re-check your plan, or restate the instructions back to yourself multiple times - that burns your output budget and means you risk never finishing the actual report the user needs to see. When you're done thinking, output the exact line @@@REPORT_START@@@ on its own line, then the full report (starting with "## What's on your plate"), then the exact line @@@REPORT_END@@@ on its own line. Put nothing else - no notes, no self-checks, no re-statements - between those two marker lines. Everything between them is shown to the user verbatim. --- DATA: {"".join(sections)} """ return prompt