Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| from groq import Groq, APITimeoutError | |
| import os | |
| # Set up the page configuration | |
| st.set_page_config(page_title="Fitness and Nutrition Coaching Chatbot", page_icon="🏋️♂️") | |
| # Read the API key from environment variables or Streamlit secrets | |
| # groq_api_key = st.secrets["GROQ_API_KEY"] | |
| # client = Groq(api_key=groq_api_key, timeout=60) | |
| groq_api_key = st.secrets["groq"]["api_key"] | |
| client = Groq(api_key=groq_api_key, timeout=60) | |
| # Session state for chats and editing | |
| if "chats" not in st.session_state: | |
| # Start with one empty chat | |
| st.session_state.chats = [{"first_query": None, "history": []}] | |
| if "current_chat_index" not in st.session_state: | |
| st.session_state.current_chat_index = 0 # Start with the first chat | |
| if "editing_query_index" not in st.session_state: | |
| st.session_state.editing_query_index = None # Initialize editing mode | |
| # Helper function to truncate long text with ellipsis | |
| def truncate_query(query, max_len=40): | |
| if len(query) > max_len: | |
| # Show only the first 'max_len' characters, followed by ellipsis | |
| return query[:max_len] + "..." | |
| return query | |
| def handle_submit(user_input, is_edit=False): | |
| if user_input: | |
| current_chat = st.session_state.chats[st.session_state.current_chat_index] | |
| # Generate the response using Groq | |
| try: | |
| chat_completion = client.chat.completions.create( | |
| messages=[ | |
| { | |
| "role": "system", | |
| "content": """You are a knowledgeable, friendly, and professional Fitness and Nutrition Coach. Your goal is to provide evidence-based, practical, and personalized advice on fitness, nutrition, and overall health. Follow these guidelines: | |
| Expertise: Offer accurate, science-backed information on topics like workout routines, diet plans, macronutrients (proteins, fats, carbs), micronutrients (vitamins, minerals), calorie intake, hydration, and healthy lifestyle habits. | |
| Personalization: Tailor your responses to the user's goals (e.g., muscle gain, fat loss, endurance training, general health). Ask clarifying questions if needed to provide better advice. However, avoid giving medical advice or diagnosing conditions. | |
| Encouragement: Motivate users with positive reinforcement and celebrate their progress, no matter how small. Help them stay consistent and focused on their goals. | |
| Clarity: Explain complex concepts in simple, easy-to-understand language. Avoid jargon unless you define it clearly. | |
| Safety: Always emphasize the importance of consulting a healthcare professional, registered dietitian, or certified trainer before making significant changes to diet, exercise, or lifestyle—especially for users with pre-existing conditions or specific health concerns. | |
| Relevance: Stay focused on fitness and nutrition topics. If the user asks unrelated questions, politely guide the conversation back to health and wellness. | |
| Balance: Promote a balanced approach to fitness and nutrition. Avoid extreme diets or workout regimens unless scientifically justified and safe. | |
| Ethics: Do not promote unhealthy behaviors, fad diets, or unverified supplements. Always prioritize the user's long-term health and well-being. | |
| Your role is to educate, inspire, and support users in achieving their fitness and nutrition goals while fostering a positive and sustainable approach to health.""" | |
| }, | |
| { | |
| "role": "user", | |
| "content": user_input, | |
| } | |
| ], | |
| model="Llama3-8b-8192", # Default model | |
| ) | |
| response = chat_completion.choices[0].message.content | |
| except APITimeoutError as e: | |
| st.write("API Timeout Error! Try again sometimes.") | |
| st.stop() | |
| if is_edit: | |
| # Update existing query and response | |
| original_response = current_chat["history"][st.session_state.editing_query_index]["response"] | |
| current_chat["history"][st.session_state.editing_query_index]["query"] = user_input | |
| current_chat["history"][st.session_state.editing_query_index]["response"] = response | |
| current_chat["history"][st.session_state.editing_query_index]["original_response"] = original_response | |
| st.session_state.editing_query_index = None # Reset edit mode | |
| else: | |
| # Add new query and response | |
| current_chat["history"].append( | |
| {"query": user_input, "response": response}) | |
| # Set the first query and rerun to update the chat title | |
| if current_chat["first_query"] is None: | |
| current_chat["first_query"] = user_input | |
| st.rerun() | |
| # Function to create a new chat | |
| def create_new_chat(): | |
| st.session_state.chats.append({"first_query": None, "history": []}) | |
| st.session_state.current_chat_index = len(st.session_state.chats) - 1 | |
| # Function to switch to a chat | |
| def switch_chat(index): | |
| st.session_state.current_chat_index = index | |
| # Function to delete a chat | |
| def delete_chat(index): | |
| del st.session_state.chats[index] | |
| if st.session_state.current_chat_index >= len(st.session_state.chats): | |
| st.session_state.current_chat_index = len(st.session_state.chats) - 1 | |
| st.rerun() | |
| # Function to delete a message | |
| def delete_message(chat_index, message_index): | |
| del st.session_state.chats[chat_index]["history"][message_index] | |
| st.rerun() | |
| # Sidebar for user instructions | |
| st.sidebar.header("Instructions") | |
| st.sidebar.markdown(""" | |
| Welcome to the Fitness and Nutrition Coaching AI Chatbot! | |
| - Ask any fitness or nutrition-related questions. | |
| - Get personalized advice and tips. | |
| """) | |
| # Sidebar buttons for creating new chats and displaying existing chats | |
| st.sidebar.title("Chats") | |
| if st.sidebar.button("Create New Chat", key="create_new_chat"): | |
| create_new_chat() | |
| for i, chat in enumerate(st.session_state.chats): | |
| chat_title = chat["first_query"] if chat["first_query"] else f"Chat {i + 1}" | |
| truncated_chat_title = truncate_query(chat_title) | |
| col1, col2 = st.sidebar.columns([1, 1]) | |
| with col1: | |
| if st.button(truncated_chat_title, key=f'chat_{i}', help="Switch to this chat"): | |
| switch_chat(i) | |
| with col2: | |
| if st.button("🗑️", key=f'delete_chat_{i}', help="Delete this chat"): | |
| delete_chat(i) | |
| # Search input for search history | |
| search_query = st.sidebar.text_input("Search History", "") | |
| # Display search history in the sidebar | |
| st.sidebar.title("Search History") | |
| current_chat = st.session_state.chats[st.session_state.current_chat_index] | |
| filtered_history = [entry for entry in current_chat["history"] if search_query.lower() in entry["query"].lower()] | |
| for i, entry in enumerate(filtered_history): | |
| query = entry["query"] | |
| truncated_query = truncate_query(query) | |
| col1, col2 = st.sidebar.columns([1, 1]) | |
| with col1: | |
| if st.button(truncated_query, key=f'history_{i}', help="Edit this query"): | |
| st.session_state.editing_query_index = i | |
| st.rerun() # Trigger rerun to show the edit input | |
| with col2: | |
| if st.button("🗑️", key=f'delete_message_{i}', help="Delete this message"): | |
| delete_message(st.session_state.current_chat_index, i) | |
| # Handle query input and edit mode | |
| if st.session_state.editing_query_index is not None: | |
| editing_index = st.session_state.editing_query_index | |
| current_chat = st.session_state.chats[st.session_state.current_chat_index] | |
| if editing_index < len(current_chat["history"]): | |
| edited_query = st.text_input( | |
| "Edit your query:", value=current_chat["history"][editing_index]["query"], key=f'edit_query_{editing_index}') | |
| if st.button("Submit Edit", key=f'submit_edit_{editing_index}', help="Submit the edited query"): | |
| handle_submit(edited_query, is_edit=True) | |
| st.rerun() # Rerun to update the view and exit edit mode | |
| else: | |
| st.session_state.editing_query_index = None # Reset edit mode if index is out of range | |
| else: | |
| user_input = st.chat_input("Ask something!") | |
| if user_input: | |
| handle_submit(user_input) | |
| # Display the chat history | |
| current_chat = st.session_state.chats[st.session_state.current_chat_index]["history"] | |
| # Display chat history with edit options | |
| for i, entry in enumerate(current_chat): | |
| if i == st.session_state.editing_query_index: | |
| continue # Skip displaying the entry currently being edited | |
| # Display query and response | |
| with st.chat_message("user"): | |
| st.markdown(entry["query"]) | |
| with st.chat_message("assistant"): | |
| st.markdown(entry["response"]) | |
| if "original_response" in entry: | |
| st.markdown(f"**Original Response:** {entry['original_response']}") | |
| col1, col2 = st.columns([1, 1]) | |
| with col1: | |
| if st.button("✏️", key=f'edit_{i}', help="Edit this query"): | |
| st.session_state.editing_query_index = i | |
| st.rerun() # Trigger rerun to show the edit input | |
| with col2: | |
| if st.button("🗑️", key=f'delete_{i}', help="Delete this message"): | |
| delete_message(st.session_state.current_chat_index, i) | |