import streamlit as st import google.generativeai as genai from PIL import Image import requests # Configure Google Generative AI library with an API key genai.configure(api_key="AIzaSyBuQHthxfR0t-3RtZC44YxTBJWN4roz-O4") # API configurations for Dobby DOBBY_API_URL = "https://api.fireworks.ai/inference/v1/chat/completions" DOBBY_API_KEY = "fw_3ZjtsywUGddwa1wGY4VvB3eW" DOBBY_LEASHED_MODEL = "accounts/sentientfoundation/models/dobby-mini-leashed-llama-3-1-8b#accounts/sentientfoundation/deployments/22e7b3fd" DOBBY_UNHINGED_MODEL = "accounts/sentientfoundation/models/dobby-mini-unhinged-llama-3-1-8b#accounts/sentientfoundation/deployments/81e155fc" # Initialize session state for tracking meals and user info if "meal_data" not in st.session_state: st.session_state.meal_data = {"Breakfast": {}, "Lunch": {}, "Dinner": {}} if "daily_totals" not in st.session_state: st.session_state.daily_totals = {"Calories": 0, "Protein": 0, "Carbs": 0, "Fat": 0} if "user_info" not in st.session_state: st.session_state.user_info = {} st.markdown(""" """, unsafe_allow_html=True) st.markdown('
Calorie Bro
', unsafe_allow_html=True) st.markdown('
Your personal AI image calorie tracker, powered by Sentient Dobby AI. Upload you breakfast, lunch and dinner, write your workout for the day and dare to get some 18+ feedback!
', unsafe_allow_html=True) # Step 1: User inputs weight (in pounds), goal, and Dobby tone if not st.session_state.user_info: st.markdown('
Step 1: Set Your Preferences
', unsafe_allow_html=True) weight = st.number_input( "Enter your weight (lbs):", min_value=50, # Minimum weight in pounds (~30 kg) max_value=1000, # Maximum weight in pounds (~300 kg) step=1, value=175 ) goal = st.selectbox("Select your goal:", ["Lose Weight", "Maintain Weight", "Gain Weight"]) tone = "Sarcastic (Unhinged)" # Default tone if st.button("Submit", help="Save your preferences to start tracking meals."): st.session_state.user_info = { "Weight": weight, "Goal": goal, "Tone": tone } st.success("Your preferences have been saved!") # Step 2: Meal tracking if st.session_state.user_info: meal = st.selectbox("Select Meal:", ["Breakfast", "Lunch", "Dinner"]) uploaded_file = st.file_uploader(f"Upload your {meal} image", type=["jpg", "jpeg", "png"]) # Functions for analysis and comments def analyze_food_with_gemini(input_prompt, image_data): model = genai.GenerativeModel("gemini-1.5-pro-latest") response = model.generate_content([input_prompt, image_data[0]]) return response.text def prepare_image_data(uploaded_file): bytes_data = uploaded_file.getvalue() return [{"mime_type": uploaded_file.type, "data": bytes_data}] def get_dobby_comment(food_name, total_calories, total_protein, total_carbs, total_fat, meal, goal, tone): selected_model = DOBBY_UNHINGED_MODEL # Default tone is sarcastic dobby_prompt = f""" The user had {meal}: {food_name}. Nutritional data: {total_calories} kcal, {total_protein} g protein, {total_carbs} g carbs, {total_fat} g fat. The user's goal is to {goal.lower()}. Provide feedback for this meal. """ response = requests.post( DOBBY_API_URL, headers={ "Authorization": f"Bearer {DOBBY_API_KEY}", "Content-Type": "application/json", }, json={ "model": selected_model, "messages": [{"role": "user", "content": dobby_prompt}], }, ) return response.json().get("choices", [{}])[0].get("message", {}).get("content", "No response") # Process uploaded meal image if uploaded_file: st.image(uploaded_file, caption=f"Uploaded {meal} Image", use_container_width=True) with st.spinner("Analyzing the image..."): try: # Prepare image data and analyze with Gemini image_data = prepare_image_data(uploaded_file) input_prompt = """ You are an expert nutritionist analyzing the food items in the image. Start by naming the meal based on the image, identify all ingredients, and estimate calories for each ingredient. Summarize the total calories, protein, carbs, and fat. Provide data in this format: Meal Name: [Name of the meal] Total Calories: X kcal Protein: X g Carbs: X g Fat: X g say nothing else """ analysis = analyze_food_with_gemini(input_prompt, image_data) # Extract analysis data lines = analysis.split("\n") food_name = lines[0].replace("Meal Name: ", "").strip() total_calories = int(lines[1].replace("Total Calories: ", "").replace("kcal", "").strip()) total_protein = int(lines[2].replace("Protein: ", "").replace("g", "").strip()) total_carbs = int(lines[3].replace("Carbs: ", "").replace("g", "").strip()) total_fat = int(lines[4].replace("Fat: ", "").replace("g", "").strip()) # Save data for this meal st.session_state.meal_data[meal] = { "Food Name": food_name, "Calories": total_calories, "Protein": total_protein, "Carbs": total_carbs, "Fat": total_fat, } # Update daily totals st.session_state.daily_totals["Calories"] += total_calories st.session_state.daily_totals["Protein"] += total_protein st.session_state.daily_totals["Carbs"] += total_carbs st.session_state.daily_totals["Fat"] += total_fat # Get Dobby's feedback dobby_comment = get_dobby_comment( food_name, total_calories, total_protein, total_carbs, total_fat, meal, st.session_state.user_info["Goal"], st.session_state.user_info["Tone"] ) # Display results in the desired format st.write( f"**{food_name}: {total_calories} kcal, {total_protein}g of Protein, {total_carbs}g of Carbs, {total_fat}g of Fat**" ) st.write(dobby_comment) except Exception as e: st.error(f"Error processing the image: {e}") # Step 3: Workout tracking and analysis if all(st.session_state.meal_data[meal] for meal in ["Breakfast", "Lunch", "Dinner"]): st.subheader("Step 3: Log Your Workout") workout_input = st.text_area( "Describe your workout or activity today (e.g., 'I walked for 30 minutes and biked for 1 hour'):", placeholder="Enter your workout activities here..." ) if st.button("Analyze Workout"): if workout_input.strip() == "": st.error("Please describe your workout before analyzing!") else: with st.spinner("Analyzing your workout..."): try: # Gemini prompt for workout analysis workout_prompt = f""" You are an expert fitness tracker. The user did the following activities today: {workout_input} Calculate the total calories burned based on the description. Provide data in this format: "X calories burned by [activity descriptions]." Say nothing else. """ # Analyze workout using Gemini for text model = genai.GenerativeModel("gemini-1.5-pro-latest") workout_analysis = model.generate_content([workout_prompt]).text.strip() st.session_state.daily_totals["Workout"] = workout_analysis # Dobby's feedback on the workout dobby_workout_prompt = f""" The user performed the following workout activities: {workout_input}. Based on the analysis, {workout_analysis}. Provide sarcastic or motivational feedback based on the user's goal to {st.session_state.user_info["Goal"].lower()}. """ dobby_workout_comment = requests.post( DOBBY_API_URL, headers={ "Authorization": f"Bearer {DOBBY_API_KEY}", "Content-Type": "application/json", }, json={ "model": DOBBY_UNHINGED_MODEL, # Default to unhinged tone "messages": [{"role": "user", "content": dobby_workout_prompt}], }, ).json().get("choices", [{}])[0].get("message", {}).get("content", "No response") st.session_state.daily_totals["Workout Comment"] = dobby_workout_comment # Display workout results st.write(f"**{workout_analysis}**") st.write(dobby_workout_comment) except Exception as e: st.error(f"Error processing workout: {e}") # Step 4: Daily Summary if "Workout" in st.session_state.daily_totals: st.subheader("Daily Summary") st.write(f"**Total Calories Consumed:** {st.session_state.daily_totals['Calories']} kcal") st.write(f"**Total Protein:** {st.session_state.daily_totals['Protein']} g") st.write(f"**Total Carbs:** {st.session_state.daily_totals['Carbs']} g") st.write(f"**Total Fat:** {st.session_state.daily_totals['Fat']} g") st.write(f"**Workout Summary:** {st.session_state.daily_totals['Workout']}") # Final Dobby comment for the entire day final_prompt = f""" The user had the following meals today: Breakfast: {st.session_state.meal_data['Breakfast']['Food Name']} Lunch: {st.session_state.meal_data['Lunch']['Food Name']} Dinner: {st.session_state.meal_data['Dinner']['Food Name']} Total daily intake: {st.session_state.daily_totals['Calories']} kcal, {st.session_state.daily_totals['Protein']} g protein, {st.session_state.daily_totals['Carbs']} g carbs, {st.session_state.daily_totals['Fat']} g fat. They also did the following workout: {st.session_state.daily_totals['Workout']} Provide a summary of their day, considering both diet AND workout, and feedback for improvement. """ final_comment = get_dobby_comment( "", st.session_state.daily_totals["Calories"], st.session_state.daily_totals["Protein"], st.session_state.daily_totals["Carbs"], st.session_state.daily_totals["Fat"], "Daily Summary", st.session_state.user_info["Goal"], st.session_state.user_info["Tone"] ) st.write(final_comment)