joyjonesmark commited on
Commit
1d2cc0e
Β·
1 Parent(s): f8a9372

Add application file

Browse files
Files changed (2) hide show
  1. app.py +195 -0
  2. requiremnt.txt +52 -0
app.py ADDED
@@ -0,0 +1,195 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from groq import Groq, APITimeoutError
3
+ import os
4
+
5
+ # Set up the page configuration
6
+ st.set_page_config(page_title="Fitness and Nutrition Coaching Chatbot", page_icon="πŸ‹οΈβ€β™‚οΈ")
7
+
8
+ # Read the API key from environment variables or Streamlit secrets
9
+ groq_api_key = os.getenv("GROQ_API_KEY") or st.secrets["GROQ_API_KEY"]
10
+
11
+ client = Groq(api_key=groq_api_key, timeout=60)
12
+
13
+ # Session state for chats and editing
14
+ if "chats" not in st.session_state:
15
+ # Start with one empty chat
16
+ st.session_state.chats = [{"first_query": None, "history": []}]
17
+
18
+ if "current_chat_index" not in st.session_state:
19
+ st.session_state.current_chat_index = 0 # Start with the first chat
20
+
21
+ if "editing_query_index" not in st.session_state:
22
+ st.session_state.editing_query_index = None # Initialize editing mode
23
+
24
+ # Helper function to truncate long text with ellipsis
25
+ def truncate_query(query, max_len=40):
26
+ if len(query) > max_len:
27
+ # Show only the first 'max_len' characters, followed by ellipsis
28
+ return query[:max_len] + "..."
29
+ return query
30
+
31
+ def handle_submit(user_input, is_edit=False):
32
+ if user_input:
33
+ current_chat = st.session_state.chats[st.session_state.current_chat_index]
34
+
35
+ # Generate the response using Groq
36
+ try:
37
+ chat_completion = client.chat.completions.create(
38
+ messages=[
39
+ {
40
+ "role": "system",
41
+ "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:
42
+
43
+ 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.
44
+
45
+ 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.
46
+
47
+ Encouragement: Motivate users with positive reinforcement and celebrate their progress, no matter how small. Help them stay consistent and focused on their goals.
48
+
49
+ Clarity: Explain complex concepts in simple, easy-to-understand language. Avoid jargon unless you define it clearly.
50
+
51
+ 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.
52
+
53
+ Relevance: Stay focused on fitness and nutrition topics. If the user asks unrelated questions, politely guide the conversation back to health and wellness.
54
+
55
+ Balance: Promote a balanced approach to fitness and nutrition. Avoid extreme diets or workout regimens unless scientifically justified and safe.
56
+
57
+ Ethics: Do not promote unhealthy behaviors, fad diets, or unverified supplements. Always prioritize the user's long-term health and well-being.
58
+
59
+ 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."""
60
+ },
61
+ {
62
+ "role": "user",
63
+ "content": user_input,
64
+ }
65
+ ],
66
+ model="Llama3-8b-8192", # Default model
67
+ )
68
+ response = chat_completion.choices[0].message.content
69
+
70
+ except APITimeoutError as e:
71
+ st.write("API Timeout Error! Try again sometimes.")
72
+ st.stop()
73
+
74
+ if is_edit:
75
+ # Update existing query and response
76
+ original_response = current_chat["history"][st.session_state.editing_query_index]["response"]
77
+ current_chat["history"][st.session_state.editing_query_index]["query"] = user_input
78
+ current_chat["history"][st.session_state.editing_query_index]["response"] = response
79
+ current_chat["history"][st.session_state.editing_query_index]["original_response"] = original_response
80
+ st.session_state.editing_query_index = None # Reset edit mode
81
+ else:
82
+ # Add new query and response
83
+ current_chat["history"].append(
84
+ {"query": user_input, "response": response})
85
+
86
+ # Set the first query and rerun to update the chat title
87
+ if current_chat["first_query"] is None:
88
+ current_chat["first_query"] = user_input
89
+ st.rerun()
90
+
91
+ # Function to create a new chat
92
+ def create_new_chat():
93
+ st.session_state.chats.append({"first_query": None, "history": []})
94
+ st.session_state.current_chat_index = len(st.session_state.chats) - 1
95
+
96
+ # Function to switch to a chat
97
+ def switch_chat(index):
98
+ st.session_state.current_chat_index = index
99
+
100
+ # Function to delete a chat
101
+ def delete_chat(index):
102
+ del st.session_state.chats[index]
103
+ if st.session_state.current_chat_index >= len(st.session_state.chats):
104
+ st.session_state.current_chat_index = len(st.session_state.chats) - 1
105
+ st.rerun()
106
+
107
+ # Function to delete a message
108
+ def delete_message(chat_index, message_index):
109
+ del st.session_state.chats[chat_index]["history"][message_index]
110
+ st.rerun()
111
+
112
+ # Sidebar for user instructions
113
+ st.sidebar.header("Instructions")
114
+ st.sidebar.markdown("""
115
+ Welcome to the Fitness and Nutrition Coaching AI Chatbot!
116
+ - Ask any fitness or nutrition-related questions.
117
+ - Get personalized advice and tips.
118
+ """)
119
+
120
+ # Sidebar buttons for creating new chats and displaying existing chats
121
+ st.sidebar.title("Chats")
122
+ if st.sidebar.button("Create New Chat", key="create_new_chat"):
123
+ create_new_chat()
124
+
125
+ for i, chat in enumerate(st.session_state.chats):
126
+ chat_title = chat["first_query"] if chat["first_query"] else f"Chat {i + 1}"
127
+ truncated_chat_title = truncate_query(chat_title)
128
+ col1, col2 = st.sidebar.columns([1, 1])
129
+ with col1:
130
+ if st.button(truncated_chat_title, key=f'chat_{i}', help="Switch to this chat"):
131
+ switch_chat(i)
132
+ with col2:
133
+ if st.button("πŸ—‘οΈ", key=f'delete_chat_{i}', help="Delete this chat"):
134
+ delete_chat(i)
135
+
136
+ # Search input for search history
137
+ search_query = st.sidebar.text_input("Search History", "")
138
+
139
+ # Display search history in the sidebar
140
+ st.sidebar.title("Search History")
141
+ current_chat = st.session_state.chats[st.session_state.current_chat_index]
142
+ filtered_history = [entry for entry in current_chat["history"] if search_query.lower() in entry["query"].lower()]
143
+
144
+ for i, entry in enumerate(filtered_history):
145
+ query = entry["query"]
146
+ truncated_query = truncate_query(query)
147
+ col1, col2 = st.sidebar.columns([1, 1])
148
+ with col1:
149
+ if st.button(truncated_query, key=f'history_{i}', help="Edit this query"):
150
+ st.session_state.editing_query_index = i
151
+ st.rerun() # Trigger rerun to show the edit input
152
+ with col2:
153
+ if st.button("πŸ—‘οΈ", key=f'delete_message_{i}', help="Delete this message"):
154
+ delete_message(st.session_state.current_chat_index, i)
155
+
156
+ # Handle query input and edit mode
157
+ if st.session_state.editing_query_index is not None:
158
+ editing_index = st.session_state.editing_query_index
159
+ current_chat = st.session_state.chats[st.session_state.current_chat_index]
160
+ if editing_index < len(current_chat["history"]):
161
+ edited_query = st.text_input(
162
+ "Edit your query:", value=current_chat["history"][editing_index]["query"], key=f'edit_query_{editing_index}')
163
+ if st.button("Submit Edit", key=f'submit_edit_{editing_index}', help="Submit the edited query"):
164
+ handle_submit(edited_query, is_edit=True)
165
+ st.rerun() # Rerun to update the view and exit edit mode
166
+ else:
167
+ st.session_state.editing_query_index = None # Reset edit mode if index is out of range
168
+ else:
169
+ user_input = st.chat_input("Ask something!")
170
+ if user_input:
171
+ handle_submit(user_input)
172
+
173
+ # Display the chat history
174
+ current_chat = st.session_state.chats[st.session_state.current_chat_index]["history"]
175
+
176
+ # Display chat history with edit options
177
+ for i, entry in enumerate(current_chat):
178
+ if i == st.session_state.editing_query_index:
179
+ continue # Skip displaying the entry currently being edited
180
+
181
+ # Display query and response
182
+ with st.chat_message("user"):
183
+ st.markdown(entry["query"])
184
+ with st.chat_message("assistant"):
185
+ st.markdown(entry["response"])
186
+ if "original_response" in entry:
187
+ st.markdown(f"**Original Response:** {entry['original_response']}")
188
+ col1, col2 = st.columns([1, 1])
189
+ with col1:
190
+ if st.button("✏️", key=f'edit_{i}', help="Edit this query"):
191
+ st.session_state.editing_query_index = i
192
+ st.rerun() # Trigger rerun to show the edit input
193
+ with col2:
194
+ if st.button("πŸ—‘οΈ", key=f'delete_{i}', help="Delete this message"):
195
+ delete_message(st.session_state.current_chat_index, i)
requiremnt.txt ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ altair==5.5.0
2
+ annotated-types==0.7.0
3
+ anyio==4.8.0
4
+ attrs==25.1.0
5
+ blinker==1.9.0
6
+ cachetools==5.5.1
7
+ certifi==2025.1.31
8
+ charset-normalizer==3.4.1
9
+ click==8.1.8
10
+ colorama==0.4.6
11
+ distro==1.9.0
12
+ gitdb==4.0.12
13
+ GitPython==3.1.44
14
+ groq==0.18.0
15
+ h11==0.14.0
16
+ httpcore==1.0.7
17
+ httpx==0.28.1
18
+ idna==3.10
19
+ Jinja2==3.1.5
20
+ jsonschema==4.23.0
21
+ jsonschema-specifications==2024.10.1
22
+ markdown-it-py==3.0.0
23
+ MarkupSafe==3.0.2
24
+ mdurl==0.1.2
25
+ narwhals==1.27.1
26
+ numpy==2.2.3
27
+ packaging==24.2
28
+ pandas==2.2.3
29
+ pillow==11.1.0
30
+ protobuf==5.29.3
31
+ pyarrow==19.0.1
32
+ pydantic==2.10.6
33
+ pydantic_core==2.27.2
34
+ pydeck==0.9.1
35
+ Pygments==2.19.1
36
+ python-dateutil==2.9.0.post0
37
+ pytz==2025.1
38
+ referencing==0.36.2
39
+ requests==2.32.3
40
+ rich==13.9.4
41
+ rpds-py==0.22.3
42
+ six==1.17.0
43
+ smmap==5.0.2
44
+ sniffio==1.3.1
45
+ streamlit==1.42.1
46
+ tenacity==9.0.0
47
+ toml==0.10.2
48
+ tornado==6.4.2
49
+ typing_extensions==4.12.2
50
+ tzdata==2025.1
51
+ urllib3==2.3.0
52
+ watchdog==6.0.0