Spaces:
Configuration error
Configuration error
File size: 5,737 Bytes
62ed149 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | import streamlit as st
import cv2
import numpy as np
from google import genai
from PIL import Image
# Initialize Gemini Client
client = genai.Client()
# Force full viewport usage to widen the camera layout frame
st.set_page_config(page_title="ClariFood", page_icon="🛡️", layout="wide")
st.title("🛡️ ClariFood: Conversational Diet Intelligence")
st.write("A production-hardened hybrid edge/cloud system with dynamic session memory.")
st.markdown("---")
# --- STEP 1: CONTEXT INJECTION DECK (SIDEBAR) ---
st.sidebar.header("👤 Dynamic Health Profile")
goal_options = ["Weight Loss", "Muscle Gain / Clean Bulk", "Diabetes Management", "Hypertension Control", "Gluten-Free Induction"]
selected_goals = st.sidebar.multiselect("Primary Objectives", options=goal_options)
# Custom Goal Input Gate
custom_goal_active = st.sidebar.checkbox("Inject custom targets?")
custom_goal_text = ""
if custom_goal_active:
custom_goal_text = st.sidebar.text_input("Type custom health profile constraints:")
allergy_options = ["Dairy", "Nuts", "Gluten", "Soy", "Artificial Sweeteners", "Preservatives"]
selected_allergies = st.sidebar.multiselect("STRICT Avoidances / Allergies", options=allergy_options)
additional_notes = st.sidebar.text_area("Narrative Clinical Notes (e.g., medical conditions):")
# Construct the master string block
final_goals = selected_goals + ([custom_goal_text] if custom_goal_text else [])
user_profile_context = f"""
USER HEALTH PROFILE DOSSIER:
- Objectives: {', '.join(final_goals) if final_goals else 'General Fitness Check'}
- Strict Allergens to Flag: {', '.join(selected_allergies) if selected_allergies else 'None specified'}
- Medical/Narrative Notes: {additional_notes if additional_notes else 'None provided'}
"""
# --- STEP 2: CONVERSATIONAL MEMORY INITIALIZATION ---
if "chat_history" not in st.session_state:
st.session_state.chat_history = []
if "vault_images" not in st.session_state:
st.session_state.vault_images = []
# --- STEP 3: MULTI-IMAGE ACQUISITION CANVAS ---
st.subheader("📸 Frame Capture Pipeline")
col_cam, col_vault = st.columns([2, 3])
with col_cam:
captured_file = st.camera_input("Position product packaging in center view")
if captured_file is not None:
img = Image.open(captured_file)
# Guard against duplicates inside the active frame cycle
if len(st.session_state.vault_images) == 0 or captured_file.name != st.session_state.get("last_uploaded_name", ""):
st.session_state.vault_images.append(img)
st.session_state.last_uploaded_name = captured_file.name
st.success(f"Frame buffered into system memory! Canvas Count: {len(st.session_state.vault_images)}")
with col_vault:
if st.session_state.vault_images:
st.write("⚡ **Buffered Frame Stack Active:**")
# Render thumbnails of all taken photos side-by-side
thumb_cols = st.columns(min(len(st.session_state.vault_images), 4))
for idx, thumb_img in enumerate(st.session_state.vault_images):
with thumb_cols[idx % 4]:
st.image(thumb_img, caption=f"Scan #{idx+1}", width=120)
if st.button("🗑️ Clear Image Stack"):
st.session_state.vault_images = []
st.rerun()
st.markdown("---")
# --- STEP 4: INTERACTIVE CHAT ENGINE LAYOUT ---
st.subheader("💬 AI Clinical Consultation Stream")
# Render previous conversational statements
for message in st.session_state.chat_history:
with st.chat_message(message["role"]):
st.markdown(message["content"])
# System Execution Prompter
if user_message := st.chat_input("Ask a question about your scanned items..."):
# 1. Display User Message Instantly
st.session_state.chat_history.append({"role": "user", "content": user_message})
with st.chat_message("user"):
st.markdown(user_message)
# 2. Build Multi-modal Prompt Strategy
# Construct systemic ground truth logic framework
system_logic_prompt = f"""
You are an expert digital dietitian. You are analyzing an interactive product scan loop.
CRITICAL OPERATION PROTOCOLS:
1. Cross-reference all inputs against this profile context: {user_profile_context}
2. Analyze the attached sequence of product photos sequentially.
3. If the user's query requires finer granular data that you cannot see in the current image stack, or if a photo is unclear, DO NOT guess. State your initial observation and explicitly request the user to take an additional focused scan.
CURRENT CHAT HISTORY DIALOGUE FOR TRACKING CONTEXT:
"""
# Pack background context strings, active image arrays, and current input together
payload = [system_logic_prompt]
# Compile chat history text strings into payload
for msg in st.session_state.chat_history[:-1]:
payload.append(f"{msg['role'].upper()}: {msg['content']}\n")
# Inject our list of images directly into the multimodal generation array
payload.extend(st.session_state.vault_images)
# Inject current fresh query prompt
payload.append(f"CURRENT USER INQUIRY: {user_message}\nASSISTANT SYSTEM OUTPUT:")
# 3. Call Cloud Model Infrastructure
with st.chat_message("assistant"):
with st.spinner("Analyzing data streams..."):
try:
response = client.models.generate_content(
model='gemini-2.5-flash',
contents=payload
)
st.markdown(response.text)
st.session_state.chat_history.append({"role": "assistant", "content": response.text})
except Exception as e:
st.error(f"Execution Error: {e}")
|