chat-bot / app.py
joyjonesmark's picture
modify and added
31c0684
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)