Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,320 +1,3 @@
|
|
| 1 |
-
# ############################################################################################################
|
| 2 |
-
# # Importing Libraries
|
| 3 |
-
|
| 4 |
-
# import streamlit as st
|
| 5 |
-
# import hmac
|
| 6 |
-
# import pandas as pd
|
| 7 |
-
# import random
|
| 8 |
-
# import os
|
| 9 |
-
# import time
|
| 10 |
-
# import base64
|
| 11 |
-
# import logging
|
| 12 |
-
# import io
|
| 13 |
-
# import config
|
| 14 |
-
# from openai import OpenAI
|
| 15 |
-
|
| 16 |
-
# # Set up logging
|
| 17 |
-
# logging.basicConfig(filename='app.log', level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
|
| 18 |
-
|
| 19 |
-
# ############################################################################################################
|
| 20 |
-
# # Password protection
|
| 21 |
-
|
| 22 |
-
# def check_credentials():
|
| 23 |
-
# """Returns `True` if the user had the correct username and password."""
|
| 24 |
-
|
| 25 |
-
# def credentials_entered():
|
| 26 |
-
# """Checks whether the entered username and password are correct."""
|
| 27 |
-
# if (
|
| 28 |
-
# hmac.compare_digest(st.session_state["username"], st.secrets["username"]) and
|
| 29 |
-
# hmac.compare_digest(st.session_state["password"], st.secrets["password"])
|
| 30 |
-
# ):
|
| 31 |
-
# st.session_state["credentials_correct"] = True
|
| 32 |
-
# del st.session_state["username"] # Don't store the username.
|
| 33 |
-
# del st.session_state["password"] # Don't store the password.
|
| 34 |
-
# else:
|
| 35 |
-
# st.session_state["credentials_correct"] = False
|
| 36 |
-
|
| 37 |
-
# # Return True if the credentials are validated.
|
| 38 |
-
# if st.session_state.get("credentials_correct", False):
|
| 39 |
-
# return True
|
| 40 |
-
|
| 41 |
-
# # Show input for username and password.
|
| 42 |
-
# st.text_input("Username", on_change=credentials_entered, key="username")
|
| 43 |
-
# st.text_input("Password", type="password", on_change=credentials_entered, key="password")
|
| 44 |
-
|
| 45 |
-
# if "credentials_correct" in st.session_state:
|
| 46 |
-
# logging.warning("Invalid login attempt") # Log invalid login attempts
|
| 47 |
-
# return False
|
| 48 |
-
|
| 49 |
-
# if not check_credentials():
|
| 50 |
-
# st.stop() # Do not continue if check_credentials is not True.
|
| 51 |
-
# else:
|
| 52 |
-
# logging.info("Successful login") # Log successful logins
|
| 53 |
-
|
| 54 |
-
# ############################################################################################################
|
| 55 |
-
# # Streamlit app layout
|
| 56 |
-
|
| 57 |
-
# # Set the page to wide or centered mode
|
| 58 |
-
# st.set_page_config(layout="wide")
|
| 59 |
-
|
| 60 |
-
# # Load the terms file into a DataFrame
|
| 61 |
-
# df = pd.read_csv(config.default_terms_csv)
|
| 62 |
-
|
| 63 |
-
# # Streamlit app layout
|
| 64 |
-
# st.title(config.app_title)
|
| 65 |
-
# st.markdown(config.intro_para)
|
| 66 |
-
# st.caption(config.app_author)
|
| 67 |
-
# # st.sidebar.title(config.sidebar_title)
|
| 68 |
-
# # with st.sidebar:
|
| 69 |
-
# # with st.expander("Click here for instructions."):
|
| 70 |
-
# # st.write(config.sidebar_instructions)
|
| 71 |
-
|
| 72 |
-
# ############################################################################################################
|
| 73 |
-
# # File Uploader in sidebar
|
| 74 |
-
|
| 75 |
-
# # Load terms from a CSV file
|
| 76 |
-
# def load_terms(file_input):
|
| 77 |
-
# try:
|
| 78 |
-
# if isinstance(file_input, str):
|
| 79 |
-
# data = pd.read_csv(file_input)
|
| 80 |
-
# else:
|
| 81 |
-
# data = pd.read_csv(io.StringIO(file_input.read().decode('utf-8')))
|
| 82 |
-
# return data
|
| 83 |
-
# except Exception as e:
|
| 84 |
-
# st.error(f"An error occurred while loading the file: {str(e)}")
|
| 85 |
-
# logging.exception(f"Error loading file: {e}")
|
| 86 |
-
|
| 87 |
-
# # Function to create a download link for a file
|
| 88 |
-
# def create_download_link(file_path, file_name):
|
| 89 |
-
# try:
|
| 90 |
-
# with open(file_path, "rb") as file:
|
| 91 |
-
# file_content = file.read()
|
| 92 |
-
# encoded_content = base64.b64encode(file_content).decode("utf-8")
|
| 93 |
-
# download_link = f'<a href="data:file/csv;base64,{encoded_content}" download="{file_name}">Download {file_name}</a>'
|
| 94 |
-
# return download_link
|
| 95 |
-
# except FileNotFoundError:
|
| 96 |
-
# error_message = f"The file {file_name} was not found."
|
| 97 |
-
# st.error(error_message)
|
| 98 |
-
# logging.exception(error_message)
|
| 99 |
-
# except Exception as e:
|
| 100 |
-
# error_message = f"An error occurred: {str(e)}"
|
| 101 |
-
# st.error(error_message)
|
| 102 |
-
# logging.exception(error_message)
|
| 103 |
-
|
| 104 |
-
# # Function to extract the first column values
|
| 105 |
-
# def get_first_column_values(df):
|
| 106 |
-
# if not df.empty:
|
| 107 |
-
# return df.iloc[:, 0].tolist()
|
| 108 |
-
# else:
|
| 109 |
-
# return []
|
| 110 |
-
|
| 111 |
-
# # Download link for the template file
|
| 112 |
-
# template_file_path = config.default_terms_csv
|
| 113 |
-
|
| 114 |
-
# # File Uploader
|
| 115 |
-
# uploaded_file = config.default_terms_csv#st.sidebar.file_uploader(" ", type=["csv"])
|
| 116 |
-
# if uploaded_file is not None:
|
| 117 |
-
# logging.info(f"File uploaded: {uploaded_file.name}")
|
| 118 |
-
# st.session_state.uploaded_file = uploaded_file
|
| 119 |
-
|
| 120 |
-
# # Load terms from the file
|
| 121 |
-
# if 'uploaded_file' in st.session_state and st.session_state.uploaded_file is not None:
|
| 122 |
-
# terms = load_terms(st.session_state.uploaded_file)
|
| 123 |
-
# else:
|
| 124 |
-
# terms = load_terms(template_file_path)
|
| 125 |
-
|
| 126 |
-
# # Extract first column values
|
| 127 |
-
# term_list = get_first_column_values(terms)
|
| 128 |
-
|
| 129 |
-
# # st.sidebar.markdown(create_download_link(template_file_path, "terms.csv"), unsafe_allow_html=True)
|
| 130 |
-
|
| 131 |
-
# # # line break in the sidebar
|
| 132 |
-
# # st.sidebar.markdown('<hr>', unsafe_allow_html=True)
|
| 133 |
-
|
| 134 |
-
# ############################################################################################################
|
| 135 |
-
# # Term Selection and session state
|
| 136 |
-
|
| 137 |
-
# # Initialize the session state variables for selected term, context, and display messages
|
| 138 |
-
# if 'selected_term' not in st.session_state:
|
| 139 |
-
# st.session_state.selected_term = None
|
| 140 |
-
# if 'selected_context' not in st.session_state:
|
| 141 |
-
# st.session_state.selected_context = None
|
| 142 |
-
# if 'display_messages' not in st.session_state:
|
| 143 |
-
# st.session_state.display_messages = []
|
| 144 |
-
|
| 145 |
-
# # Initialize session states for the selected term, counter, and display flag
|
| 146 |
-
# if 'display_term' not in st.session_state:
|
| 147 |
-
# st.session_state.display_term = False
|
| 148 |
-
# if 'initial_message_displayed' not in st.session_state:
|
| 149 |
-
# st.session_state.initial_message_displayed = False
|
| 150 |
-
|
| 151 |
-
# # Initialize state to track the previously selected term
|
| 152 |
-
# if 'old_term' not in st.session_state:
|
| 153 |
-
# st.session_state.old_term = None
|
| 154 |
-
|
| 155 |
-
# # Dropdown menu for selecting a term
|
| 156 |
-
# selected_term = st.selectbox('**SELECT FROM THE DROPDOWN MENU**', term_list)
|
| 157 |
-
|
| 158 |
-
# if selected_term:
|
| 159 |
-
# # If a new term is selected (including first time selection), reset or show the message
|
| 160 |
-
# if selected_term != st.session_state.old_term:
|
| 161 |
-
# user_message = f"What is one thing you know about '{selected_term}'? What do you want to know about it? This could include a definition, examples, misconceptions, associations with other course terms, opinions, etc."
|
| 162 |
-
# st.session_state["display_messages"].append({"role": "user", "content": user_message})
|
| 163 |
-
# # Update old_term in session state
|
| 164 |
-
# st.session_state.old_term = selected_term
|
| 165 |
-
|
| 166 |
-
# selected_context = terms.loc[terms['TERM'] == selected_term, 'CONTEXT'].values[0]
|
| 167 |
-
# st.session_state.selected_term = selected_term
|
| 168 |
-
# st.session_state.selected_context = selected_context
|
| 169 |
-
# st.session_state.display_term = True
|
| 170 |
-
|
| 171 |
-
# # Update the prompt for the API
|
| 172 |
-
# updated_prompt = config.term_prompt(st.session_state.selected_term, st.session_state.selected_context, term_list)
|
| 173 |
-
|
| 174 |
-
# else:
|
| 175 |
-
# # If nothing is selected or the selection is cleared, reset the old_term
|
| 176 |
-
# st.session_state.old_term = None
|
| 177 |
-
|
| 178 |
-
# # Display the selected term and its context
|
| 179 |
-
# if st.session_state.display_term and st.session_state.selected_term:
|
| 180 |
-
# st.header(st.session_state.selected_term)
|
| 181 |
-
|
| 182 |
-
# with st.expander("INSTRUCTIONS FOR STUDENTS:"):
|
| 183 |
-
# st.markdown(config.instructions)
|
| 184 |
-
# # with st.expander("**INSTRUCTORS**: For a look at the current terms file driving the interaction, click here:"):
|
| 185 |
-
# # st.markdown("This is the terms.csv file that drives the interaction. You can edit this file to change the terms and context that the chatbot uses. You may add any term or phrase. You may leave the context blank if you prefer or you can add anything relevant that the GPT does not normally know about the term. This may include relevant learning objectives, course examples, notable scientists, assessment dates, syllabus information, etc.")
|
| 186 |
-
# # st.table(df)
|
| 187 |
-
# # with st.expander("**INSTRUCTORS**: For a look at the prompt driving the chatbot, click here:"):
|
| 188 |
-
# # prompt_text = config.term_prompt(st.session_state.selected_term, st.session_state.selected_context, term_list)
|
| 189 |
-
# # st.markdown(prompt_text)
|
| 190 |
-
|
| 191 |
-
# ############################################################################################################
|
| 192 |
-
# # ChatGPT
|
| 193 |
-
# # Initialize the OpenAI client
|
| 194 |
-
# client = OpenAI(api_key=st.secrets["OPENAI_API_KEY"])
|
| 195 |
-
|
| 196 |
-
# # Initialize the session state variables if they don't exist
|
| 197 |
-
# if "openai_model" not in st.session_state:
|
| 198 |
-
# st.session_state["openai_model"] = config.ai_model
|
| 199 |
-
|
| 200 |
-
# if "display_messages" not in st.session_state:
|
| 201 |
-
# st.session_state.display_messages = []
|
| 202 |
-
|
| 203 |
-
# # Update initial_context with the latest selected term and context
|
| 204 |
-
# if st.session_state.get('selected_term') and st.session_state.get('selected_context'):
|
| 205 |
-
# updated_prompt = config.term_prompt(st.session_state.selected_term, st.session_state.selected_context, term_list)
|
| 206 |
-
# # Replace the initial context in display_messages with the updated prompt
|
| 207 |
-
# if st.session_state.display_messages:
|
| 208 |
-
# st.session_state.display_messages[0]["content"] = updated_prompt
|
| 209 |
-
# else:
|
| 210 |
-
# st.session_state.display_messages = [{"role": "system", "content": updated_prompt}]
|
| 211 |
-
|
| 212 |
-
# # Get user input
|
| 213 |
-
# prompt = st.chat_input("What do you know? What do you want to know?")
|
| 214 |
-
|
| 215 |
-
# # Input for new messages
|
| 216 |
-
# if prompt:
|
| 217 |
-
# # Ensure the initial context is in the session state, add the user's message
|
| 218 |
-
# if not st.session_state["display_messages"]:
|
| 219 |
-
# st.session_state["display_messages"].append(initial_context)
|
| 220 |
-
# st.session_state["display_messages"].append({"role": "user", "content": prompt})
|
| 221 |
-
|
| 222 |
-
# # Function to reset all chat-related session state
|
| 223 |
-
# def reset_chat_history():
|
| 224 |
-
# st.session_state["display_messages"] = []
|
| 225 |
-
# # Reset other chat-related session states if they exist
|
| 226 |
-
# if 'selected_term' in st.session_state:
|
| 227 |
-
# st.session_state.selected_term = None
|
| 228 |
-
# if 'selected_context' in st.session_state:
|
| 229 |
-
# st.session_state.selected_context = None
|
| 230 |
-
# if 'display_term' in st.session_state:
|
| 231 |
-
# st.session_state.display_term = False
|
| 232 |
-
# st.rerun()
|
| 233 |
-
|
| 234 |
-
# # Main chat container
|
| 235 |
-
# with st.container(height=400, border=True):
|
| 236 |
-
# # Display chat history in reverse order including new messages
|
| 237 |
-
# for message in st.session_state["display_messages"][1:]:
|
| 238 |
-
# if message["role"] == "user":
|
| 239 |
-
# with st.chat_message("user"):
|
| 240 |
-
# st.markdown(message["content"])
|
| 241 |
-
# else:
|
| 242 |
-
# with st.chat_message("assistant"):
|
| 243 |
-
# st.markdown(message["content"])
|
| 244 |
-
|
| 245 |
-
# # Generate assistant's response and add it to the messages
|
| 246 |
-
# if prompt:
|
| 247 |
-
# with st.chat_message("assistant"):
|
| 248 |
-
# try:
|
| 249 |
-
# stream = client.chat.completions.create(
|
| 250 |
-
# model=st.session_state["openai_model"],
|
| 251 |
-
# messages=[
|
| 252 |
-
# {"role": m["role"], "content": m["content"]}
|
| 253 |
-
# for m in st.session_state["display_messages"]
|
| 254 |
-
# ],
|
| 255 |
-
# stream=True,
|
| 256 |
-
# temperature=config.temperature,
|
| 257 |
-
# max_tokens=config.max_tokens,
|
| 258 |
-
# frequency_penalty=config.frequency_penalty,
|
| 259 |
-
# presence_penalty=config.presence_penalty,
|
| 260 |
-
# )
|
| 261 |
-
# response = st.write_stream(stream)
|
| 262 |
-
# # Append the full response to the session state for display
|
| 263 |
-
# st.session_state["display_messages"].append(
|
| 264 |
-
# {"role": "assistant", "content": response}
|
| 265 |
-
# )
|
| 266 |
-
# logging.info(f"User prompt: {prompt}") # Log user prompts
|
| 267 |
-
# logging.info(f"Assistant response: {response}") # Log assistant responses
|
| 268 |
-
# except Exception as e:
|
| 269 |
-
# st.error(f"An error occurred: {str(e)}")
|
| 270 |
-
# logging.exception(f"Error generating response: {e}") # Log errors
|
| 271 |
-
|
| 272 |
-
# # Add Clear Chat History button between container and warning message
|
| 273 |
-
# if st.button("Clear Chat History"):
|
| 274 |
-
# reset_chat_history()
|
| 275 |
-
# logging.info("Chat history cleared") # Log when chat history is cleared
|
| 276 |
-
|
| 277 |
-
# st.markdown(config.warning_message, unsafe_allow_html=True)
|
| 278 |
-
|
| 279 |
-
# ############################################################################################################
|
| 280 |
-
|
| 281 |
-
# # Resources and About Sections in the Sidebar
|
| 282 |
-
|
| 283 |
-
# st.sidebar.title("Resources")
|
| 284 |
-
|
| 285 |
-
# for resource in config.resources:
|
| 286 |
-
# with st.sidebar:
|
| 287 |
-
# with st.sidebar:
|
| 288 |
-
# with st.expander(resource["title"]):
|
| 289 |
-
# st.markdown(f"Description: {resource['description']}")
|
| 290 |
-
# if "url" in resource:
|
| 291 |
-
# st.markdown(f"[{resource['title']}]({resource['url']})")
|
| 292 |
-
# if "file_path" in resource:
|
| 293 |
-
# file_path = resource["file_path"]
|
| 294 |
-
# if os.path.exists(file_path):
|
| 295 |
-
# with open(file_path, "rb") as file:
|
| 296 |
-
# file_bytes = file.read()
|
| 297 |
-
# with st.spinner(f"Loading {resource['title']}..."):
|
| 298 |
-
# st.download_button(
|
| 299 |
-
# label=resource["title"],
|
| 300 |
-
# data=file_bytes,
|
| 301 |
-
# file_name=os.path.basename(file_path),
|
| 302 |
-
# mime="application/octet-stream",
|
| 303 |
-
# help=resource["description"],
|
| 304 |
-
# )
|
| 305 |
-
# else:
|
| 306 |
-
# st.warning(f"File not found: {file_path}")
|
| 307 |
-
|
| 308 |
-
# # Footer
|
| 309 |
-
# with st.sidebar:
|
| 310 |
-
# st.markdown("---")
|
| 311 |
-
|
| 312 |
-
# st.title("About")
|
| 313 |
-
|
| 314 |
-
# # Using the config objects in your Streamlit app
|
| 315 |
-
# st.markdown(config.app_creation_message, unsafe_allow_html=True)
|
| 316 |
-
# st.markdown(config.app_repo_license_message, unsafe_allow_html=True)
|
| 317 |
-
|
| 318 |
############################################################################################################
|
| 319 |
# Importing Libraries
|
| 320 |
|
|
@@ -331,12 +14,7 @@ import config
|
|
| 331 |
from openai import OpenAI
|
| 332 |
|
| 333 |
# Set up logging
|
| 334 |
-
logging.basicConfig(
|
| 335 |
-
filename='app.log',
|
| 336 |
-
level=logging.INFO,
|
| 337 |
-
format='%(asctime)s - %(levelname)s - %(message)s',
|
| 338 |
-
datefmt='%Y-%m-%d %H:%M:%S'
|
| 339 |
-
)
|
| 340 |
|
| 341 |
############################################################################################################
|
| 342 |
# Password protection
|
|
@@ -379,7 +57,7 @@ else:
|
|
| 379 |
# Set the page to wide or centered mode
|
| 380 |
st.set_page_config(layout="wide")
|
| 381 |
|
| 382 |
-
# Load the terms file into a DataFrame
|
| 383 |
df = pd.read_csv(config.default_terms_csv)
|
| 384 |
|
| 385 |
# Streamlit app layout
|
|
@@ -406,12 +84,76 @@ def get_first_column_values(local_df):
|
|
| 406 |
else:
|
| 407 |
return []
|
| 408 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 409 |
############################################################################################################
|
| 410 |
# Prepare terms (no user file uploader anymore—only config.default_terms_csv)
|
| 411 |
|
| 412 |
terms = load_terms(config.default_terms_csv)
|
| 413 |
term_list = get_first_column_values(terms)
|
| 414 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 415 |
############################################################################################################
|
| 416 |
# Term Selection and session state
|
| 417 |
|
|
@@ -422,10 +164,14 @@ if 'selected_context' not in st.session_state:
|
|
| 422 |
st.session_state.selected_context = None
|
| 423 |
if 'display_messages' not in st.session_state:
|
| 424 |
st.session_state.display_messages = []
|
|
|
|
|
|
|
| 425 |
if 'display_term' not in st.session_state:
|
| 426 |
st.session_state.display_term = False
|
| 427 |
if 'initial_message_displayed' not in st.session_state:
|
| 428 |
st.session_state.initial_message_displayed = False
|
|
|
|
|
|
|
| 429 |
if 'old_term' not in st.session_state:
|
| 430 |
st.session_state.old_term = None
|
| 431 |
|
|
@@ -433,67 +179,73 @@ if 'old_term' not in st.session_state:
|
|
| 433 |
selected_term = st.selectbox('**SELECT FROM THE DROPDOWN MENU**', term_list)
|
| 434 |
|
| 435 |
if selected_term:
|
| 436 |
-
# If a new term is selected
|
| 437 |
if selected_term != st.session_state.old_term:
|
| 438 |
-
user_message =
|
| 439 |
-
f"What is one thing you know about '{selected_term}'? What do you want to know about it? "
|
| 440 |
-
"This could include a definition, examples, misconceptions, associations with other course terms, opinions, etc."
|
| 441 |
-
)
|
| 442 |
st.session_state["display_messages"].append({"role": "user", "content": user_message})
|
|
|
|
| 443 |
st.session_state.old_term = selected_term
|
| 444 |
-
|
| 445 |
selected_context = terms.loc[terms['TERM'] == selected_term, 'CONTEXT'].values[0]
|
| 446 |
st.session_state.selected_term = selected_term
|
| 447 |
st.session_state.selected_context = selected_context
|
| 448 |
st.session_state.display_term = True
|
| 449 |
-
|
| 450 |
-
#
|
| 451 |
updated_prompt = config.term_prompt(st.session_state.selected_term, st.session_state.selected_context, term_list)
|
| 452 |
-
|
| 453 |
else:
|
|
|
|
| 454 |
st.session_state.old_term = None
|
| 455 |
|
| 456 |
-
# Display the selected term and context
|
| 457 |
if st.session_state.display_term and st.session_state.selected_term:
|
| 458 |
st.header(st.session_state.selected_term)
|
| 459 |
|
| 460 |
with st.expander("INSTRUCTIONS FOR STUDENTS:"):
|
| 461 |
st.markdown(config.instructions)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 462 |
|
| 463 |
############################################################################################################
|
| 464 |
# ChatGPT
|
| 465 |
# Initialize the OpenAI client
|
| 466 |
client = OpenAI(api_key=st.secrets["OPENAI_API_KEY"])
|
| 467 |
|
| 468 |
-
# Initialize the
|
| 469 |
if "openai_model" not in st.session_state:
|
| 470 |
st.session_state["openai_model"] = config.ai_model
|
| 471 |
|
| 472 |
-
|
|
|
|
|
|
|
|
|
|
| 473 |
if st.session_state.get('selected_term') and st.session_state.get('selected_context'):
|
| 474 |
-
updated_prompt = config.term_prompt(
|
| 475 |
-
|
| 476 |
-
st.session_state.selected_context,
|
| 477 |
-
term_list
|
| 478 |
-
)
|
| 479 |
if st.session_state.display_messages:
|
| 480 |
st.session_state.display_messages[0]["content"] = updated_prompt
|
| 481 |
else:
|
| 482 |
st.session_state.display_messages = [{"role": "system", "content": updated_prompt}]
|
| 483 |
|
| 484 |
-
#
|
| 485 |
prompt = st.chat_input("What do you know? What do you want to know?")
|
| 486 |
|
| 487 |
# Input for new messages
|
| 488 |
if prompt:
|
| 489 |
-
#
|
| 490 |
if not st.session_state["display_messages"]:
|
| 491 |
-
st.session_state["display_messages"].append(
|
| 492 |
st.session_state["display_messages"].append({"role": "user", "content": prompt})
|
| 493 |
|
| 494 |
# Function to reset all chat-related session state
|
| 495 |
def reset_chat_history():
|
| 496 |
st.session_state["display_messages"] = []
|
|
|
|
| 497 |
if 'selected_term' in st.session_state:
|
| 498 |
st.session_state.selected_term = None
|
| 499 |
if 'selected_context' in st.session_state:
|
|
@@ -502,11 +254,9 @@ def reset_chat_history():
|
|
| 502 |
st.session_state.display_term = False
|
| 503 |
st.rerun()
|
| 504 |
|
| 505 |
-
############################################################################################################
|
| 506 |
# Main chat container
|
| 507 |
-
|
| 508 |
-
|
| 509 |
-
# Display chat history in reverse order
|
| 510 |
for message in st.session_state["display_messages"][1:]:
|
| 511 |
if message["role"] == "user":
|
| 512 |
with st.chat_message("user"):
|
|
@@ -515,7 +265,7 @@ with st.container():
|
|
| 515 |
with st.chat_message("assistant"):
|
| 516 |
st.markdown(message["content"])
|
| 517 |
|
| 518 |
-
|
| 519 |
if prompt:
|
| 520 |
with st.chat_message("assistant"):
|
| 521 |
try:
|
|
@@ -532,50 +282,265 @@ with st.container():
|
|
| 532 |
presence_penalty=config.presence_penalty,
|
| 533 |
)
|
| 534 |
response = st.write_stream(stream)
|
| 535 |
-
|
| 536 |
-
|
| 537 |
-
|
|
|
|
|
|
|
|
|
|
| 538 |
except Exception as e:
|
| 539 |
st.error(f"An error occurred: {str(e)}")
|
| 540 |
-
logging.exception(f"Error generating response: {e}")
|
| 541 |
|
| 542 |
-
# Clear
|
| 543 |
if st.button("Clear Chat History"):
|
| 544 |
reset_chat_history()
|
| 545 |
-
logging.info("Chat history cleared")
|
| 546 |
|
| 547 |
st.markdown(config.warning_message, unsafe_allow_html=True)
|
| 548 |
|
| 549 |
############################################################################################################
|
|
|
|
| 550 |
# Resources and About Sections in the Sidebar
|
| 551 |
|
| 552 |
st.sidebar.title("Resources")
|
| 553 |
|
| 554 |
for resource in config.resources:
|
| 555 |
with st.sidebar:
|
| 556 |
-
with st.
|
| 557 |
-
st.
|
| 558 |
-
|
| 559 |
-
|
| 560 |
-
|
| 561 |
-
file_path
|
| 562 |
-
|
| 563 |
-
|
| 564 |
-
|
| 565 |
-
|
| 566 |
-
st.
|
| 567 |
-
|
| 568 |
-
|
| 569 |
-
|
| 570 |
-
|
| 571 |
-
|
| 572 |
-
|
| 573 |
-
|
| 574 |
-
|
| 575 |
-
|
|
|
|
|
|
|
| 576 |
with st.sidebar:
|
| 577 |
st.markdown("---")
|
|
|
|
| 578 |
st.title("About")
|
|
|
|
|
|
|
| 579 |
st.markdown(config.app_creation_message, unsafe_allow_html=True)
|
| 580 |
st.markdown(config.app_repo_license_message, unsafe_allow_html=True)
|
| 581 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
############################################################################################################
|
| 2 |
# Importing Libraries
|
| 3 |
|
|
|
|
| 14 |
from openai import OpenAI
|
| 15 |
|
| 16 |
# Set up logging
|
| 17 |
+
logging.basicConfig(filename='app.log', level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
|
| 19 |
############################################################################################################
|
| 20 |
# Password protection
|
|
|
|
| 57 |
# Set the page to wide or centered mode
|
| 58 |
st.set_page_config(layout="wide")
|
| 59 |
|
| 60 |
+
# Load the terms file into a DataFrame
|
| 61 |
df = pd.read_csv(config.default_terms_csv)
|
| 62 |
|
| 63 |
# Streamlit app layout
|
|
|
|
| 84 |
else:
|
| 85 |
return []
|
| 86 |
|
| 87 |
+
|
| 88 |
+
# # File Uploader in sidebar
|
| 89 |
+
|
| 90 |
+
# # Load terms from a CSV file
|
| 91 |
+
# def load_terms(file_input):
|
| 92 |
+
# try:
|
| 93 |
+
# if isinstance(file_input, str):
|
| 94 |
+
# data = pd.read_csv(file_input)
|
| 95 |
+
# else:
|
| 96 |
+
# data = pd.read_csv(io.StringIO(file_input.read().decode('utf-8')))
|
| 97 |
+
# return data
|
| 98 |
+
# except Exception as e:
|
| 99 |
+
# st.error(f"An error occurred while loading the file: {str(e)}")
|
| 100 |
+
# logging.exception(f"Error loading file: {e}")
|
| 101 |
+
|
| 102 |
+
# # Function to create a download link for a file
|
| 103 |
+
# def create_download_link(file_path, file_name):
|
| 104 |
+
# try:
|
| 105 |
+
# with open(file_path, "rb") as file:
|
| 106 |
+
# file_content = file.read()
|
| 107 |
+
# encoded_content = base64.b64encode(file_content).decode("utf-8")
|
| 108 |
+
# download_link = f'<a href="data:file/csv;base64,{encoded_content}" download="{file_name}">Download {file_name}</a>'
|
| 109 |
+
# return download_link
|
| 110 |
+
# except FileNotFoundError:
|
| 111 |
+
# error_message = f"The file {file_name} was not found."
|
| 112 |
+
# st.error(error_message)
|
| 113 |
+
# logging.exception(error_message)
|
| 114 |
+
# except Exception as e:
|
| 115 |
+
# error_message = f"An error occurred: {str(e)}"
|
| 116 |
+
# st.error(error_message)
|
| 117 |
+
# logging.exception(error_message)
|
| 118 |
+
|
| 119 |
+
# # Function to extract the first column values
|
| 120 |
+
# def get_first_column_values(df):
|
| 121 |
+
# if not df.empty:
|
| 122 |
+
# return df.iloc[:, 0].tolist()
|
| 123 |
+
# else:
|
| 124 |
+
# return []
|
| 125 |
+
|
| 126 |
############################################################################################################
|
| 127 |
# Prepare terms (no user file uploader anymore—only config.default_terms_csv)
|
| 128 |
|
| 129 |
terms = load_terms(config.default_terms_csv)
|
| 130 |
term_list = get_first_column_values(terms)
|
| 131 |
|
| 132 |
+
|
| 133 |
+
|
| 134 |
+
# # Download link for the template file
|
| 135 |
+
# template_file_path = config.default_terms_csv
|
| 136 |
+
|
| 137 |
+
# # File Uploader
|
| 138 |
+
# uploaded_file = config.default_terms_csv#st.sidebar.file_uploader(" ", type=["csv"])
|
| 139 |
+
# if uploaded_file is not None:
|
| 140 |
+
# logging.info(f"File uploaded: {uploaded_file.name}")
|
| 141 |
+
# st.session_state.uploaded_file = uploaded_file
|
| 142 |
+
|
| 143 |
+
# # Load terms from the file
|
| 144 |
+
# if 'uploaded_file' in st.session_state and st.session_state.uploaded_file is not None:
|
| 145 |
+
# terms = load_terms(st.session_state.uploaded_file)
|
| 146 |
+
# else:
|
| 147 |
+
# terms = load_terms(template_file_path)
|
| 148 |
+
|
| 149 |
+
# # Extract first column values
|
| 150 |
+
# term_list = get_first_column_values(terms)
|
| 151 |
+
|
| 152 |
+
# # st.sidebar.markdown(create_download_link(template_file_path, "terms.csv"), unsafe_allow_html=True)
|
| 153 |
+
|
| 154 |
+
# # # line break in the sidebar
|
| 155 |
+
# # st.sidebar.markdown('<hr>', unsafe_allow_html=True)
|
| 156 |
+
|
| 157 |
############################################################################################################
|
| 158 |
# Term Selection and session state
|
| 159 |
|
|
|
|
| 164 |
st.session_state.selected_context = None
|
| 165 |
if 'display_messages' not in st.session_state:
|
| 166 |
st.session_state.display_messages = []
|
| 167 |
+
|
| 168 |
+
# Initialize session states for the selected term, counter, and display flag
|
| 169 |
if 'display_term' not in st.session_state:
|
| 170 |
st.session_state.display_term = False
|
| 171 |
if 'initial_message_displayed' not in st.session_state:
|
| 172 |
st.session_state.initial_message_displayed = False
|
| 173 |
+
|
| 174 |
+
# Initialize state to track the previously selected term
|
| 175 |
if 'old_term' not in st.session_state:
|
| 176 |
st.session_state.old_term = None
|
| 177 |
|
|
|
|
| 179 |
selected_term = st.selectbox('**SELECT FROM THE DROPDOWN MENU**', term_list)
|
| 180 |
|
| 181 |
if selected_term:
|
| 182 |
+
# If a new term is selected (including first time selection), reset or show the message
|
| 183 |
if selected_term != st.session_state.old_term:
|
| 184 |
+
user_message = f"What is one thing you know about '{selected_term}'? What do you want to know about it? This could include a definition, examples, misconceptions, associations with other course terms, opinions, etc."
|
|
|
|
|
|
|
|
|
|
| 185 |
st.session_state["display_messages"].append({"role": "user", "content": user_message})
|
| 186 |
+
# Update old_term in session state
|
| 187 |
st.session_state.old_term = selected_term
|
| 188 |
+
|
| 189 |
selected_context = terms.loc[terms['TERM'] == selected_term, 'CONTEXT'].values[0]
|
| 190 |
st.session_state.selected_term = selected_term
|
| 191 |
st.session_state.selected_context = selected_context
|
| 192 |
st.session_state.display_term = True
|
| 193 |
+
|
| 194 |
+
# Update the prompt for the API
|
| 195 |
updated_prompt = config.term_prompt(st.session_state.selected_term, st.session_state.selected_context, term_list)
|
| 196 |
+
|
| 197 |
else:
|
| 198 |
+
# If nothing is selected or the selection is cleared, reset the old_term
|
| 199 |
st.session_state.old_term = None
|
| 200 |
|
| 201 |
+
# Display the selected term and its context
|
| 202 |
if st.session_state.display_term and st.session_state.selected_term:
|
| 203 |
st.header(st.session_state.selected_term)
|
| 204 |
|
| 205 |
with st.expander("INSTRUCTIONS FOR STUDENTS:"):
|
| 206 |
st.markdown(config.instructions)
|
| 207 |
+
# with st.expander("**INSTRUCTORS**: For a look at the current terms file driving the interaction, click here:"):
|
| 208 |
+
# st.markdown("This is the terms.csv file that drives the interaction. You can edit this file to change the terms and context that the chatbot uses. You may add any term or phrase. You may leave the context blank if you prefer or you can add anything relevant that the GPT does not normally know about the term. This may include relevant learning objectives, course examples, notable scientists, assessment dates, syllabus information, etc.")
|
| 209 |
+
# st.table(df)
|
| 210 |
+
# with st.expander("**INSTRUCTORS**: For a look at the prompt driving the chatbot, click here:"):
|
| 211 |
+
# prompt_text = config.term_prompt(st.session_state.selected_term, st.session_state.selected_context, term_list)
|
| 212 |
+
# st.markdown(prompt_text)
|
| 213 |
|
| 214 |
############################################################################################################
|
| 215 |
# ChatGPT
|
| 216 |
# Initialize the OpenAI client
|
| 217 |
client = OpenAI(api_key=st.secrets["OPENAI_API_KEY"])
|
| 218 |
|
| 219 |
+
# Initialize the session state variables if they don't exist
|
| 220 |
if "openai_model" not in st.session_state:
|
| 221 |
st.session_state["openai_model"] = config.ai_model
|
| 222 |
|
| 223 |
+
if "display_messages" not in st.session_state:
|
| 224 |
+
st.session_state.display_messages = []
|
| 225 |
+
|
| 226 |
+
# Update initial_context with the latest selected term and context
|
| 227 |
if st.session_state.get('selected_term') and st.session_state.get('selected_context'):
|
| 228 |
+
updated_prompt = config.term_prompt(st.session_state.selected_term, st.session_state.selected_context, term_list)
|
| 229 |
+
# Replace the initial context in display_messages with the updated prompt
|
|
|
|
|
|
|
|
|
|
| 230 |
if st.session_state.display_messages:
|
| 231 |
st.session_state.display_messages[0]["content"] = updated_prompt
|
| 232 |
else:
|
| 233 |
st.session_state.display_messages = [{"role": "system", "content": updated_prompt}]
|
| 234 |
|
| 235 |
+
# Get user input
|
| 236 |
prompt = st.chat_input("What do you know? What do you want to know?")
|
| 237 |
|
| 238 |
# Input for new messages
|
| 239 |
if prompt:
|
| 240 |
+
# Ensure the initial context is in the session state, add the user's message
|
| 241 |
if not st.session_state["display_messages"]:
|
| 242 |
+
st.session_state["display_messages"].append(initial_context)
|
| 243 |
st.session_state["display_messages"].append({"role": "user", "content": prompt})
|
| 244 |
|
| 245 |
# Function to reset all chat-related session state
|
| 246 |
def reset_chat_history():
|
| 247 |
st.session_state["display_messages"] = []
|
| 248 |
+
# Reset other chat-related session states if they exist
|
| 249 |
if 'selected_term' in st.session_state:
|
| 250 |
st.session_state.selected_term = None
|
| 251 |
if 'selected_context' in st.session_state:
|
|
|
|
| 254 |
st.session_state.display_term = False
|
| 255 |
st.rerun()
|
| 256 |
|
|
|
|
| 257 |
# Main chat container
|
| 258 |
+
with st.container(height=400, border=True):
|
| 259 |
+
# Display chat history in reverse order including new messages
|
|
|
|
| 260 |
for message in st.session_state["display_messages"][1:]:
|
| 261 |
if message["role"] == "user":
|
| 262 |
with st.chat_message("user"):
|
|
|
|
| 265 |
with st.chat_message("assistant"):
|
| 266 |
st.markdown(message["content"])
|
| 267 |
|
| 268 |
+
# Generate assistant's response and add it to the messages
|
| 269 |
if prompt:
|
| 270 |
with st.chat_message("assistant"):
|
| 271 |
try:
|
|
|
|
| 282 |
presence_penalty=config.presence_penalty,
|
| 283 |
)
|
| 284 |
response = st.write_stream(stream)
|
| 285 |
+
# Append the full response to the session state for display
|
| 286 |
+
st.session_state["display_messages"].append(
|
| 287 |
+
{"role": "assistant", "content": response}
|
| 288 |
+
)
|
| 289 |
+
logging.info(f"User prompt: {prompt}") # Log user prompts
|
| 290 |
+
logging.info(f"Assistant response: {response}") # Log assistant responses
|
| 291 |
except Exception as e:
|
| 292 |
st.error(f"An error occurred: {str(e)}")
|
| 293 |
+
logging.exception(f"Error generating response: {e}") # Log errors
|
| 294 |
|
| 295 |
+
# Add Clear Chat History button between container and warning message
|
| 296 |
if st.button("Clear Chat History"):
|
| 297 |
reset_chat_history()
|
| 298 |
+
logging.info("Chat history cleared") # Log when chat history is cleared
|
| 299 |
|
| 300 |
st.markdown(config.warning_message, unsafe_allow_html=True)
|
| 301 |
|
| 302 |
############################################################################################################
|
| 303 |
+
|
| 304 |
# Resources and About Sections in the Sidebar
|
| 305 |
|
| 306 |
st.sidebar.title("Resources")
|
| 307 |
|
| 308 |
for resource in config.resources:
|
| 309 |
with st.sidebar:
|
| 310 |
+
with st.sidebar:
|
| 311 |
+
with st.expander(resource["title"]):
|
| 312 |
+
st.markdown(f"Description: {resource['description']}")
|
| 313 |
+
if "url" in resource:
|
| 314 |
+
st.markdown(f"[{resource['title']}]({resource['url']})")
|
| 315 |
+
if "file_path" in resource:
|
| 316 |
+
file_path = resource["file_path"]
|
| 317 |
+
if os.path.exists(file_path):
|
| 318 |
+
with open(file_path, "rb") as file:
|
| 319 |
+
file_bytes = file.read()
|
| 320 |
+
with st.spinner(f"Loading {resource['title']}..."):
|
| 321 |
+
st.download_button(
|
| 322 |
+
label=resource["title"],
|
| 323 |
+
data=file_bytes,
|
| 324 |
+
file_name=os.path.basename(file_path),
|
| 325 |
+
mime="application/octet-stream",
|
| 326 |
+
help=resource["description"],
|
| 327 |
+
)
|
| 328 |
+
else:
|
| 329 |
+
st.warning(f"File not found: {file_path}")
|
| 330 |
+
|
| 331 |
+
# Footer
|
| 332 |
with st.sidebar:
|
| 333 |
st.markdown("---")
|
| 334 |
+
|
| 335 |
st.title("About")
|
| 336 |
+
|
| 337 |
+
# Using the config objects in your Streamlit app
|
| 338 |
st.markdown(config.app_creation_message, unsafe_allow_html=True)
|
| 339 |
st.markdown(config.app_repo_license_message, unsafe_allow_html=True)
|
| 340 |
|
| 341 |
+
# #################################################################
|
| 342 |
+
# # Streamlit app layout
|
| 343 |
+
|
| 344 |
+
# # Set the page to wide or centered mode
|
| 345 |
+
# st.set_page_config(layout="wide")
|
| 346 |
+
|
| 347 |
+
# # Load the terms file into a DataFrame using config.default_terms_csv
|
| 348 |
+
# df = pd.read_csv(config.default_terms_csv)
|
| 349 |
+
|
| 350 |
+
# # Streamlit app layout
|
| 351 |
+
# st.title(config.app_title)
|
| 352 |
+
# st.markdown(config.intro_para)
|
| 353 |
+
# st.caption(config.app_author)
|
| 354 |
+
|
| 355 |
+
# ############################################################################################################
|
| 356 |
+
# # Loading Terms
|
| 357 |
+
|
| 358 |
+
# def load_terms(file_path):
|
| 359 |
+
# """Loads the CSV from the directory."""
|
| 360 |
+
# try:
|
| 361 |
+
# return pd.read_csv(file_path)
|
| 362 |
+
# except Exception as e:
|
| 363 |
+
# st.error(f"An error occurred while loading the file: {str(e)}")
|
| 364 |
+
# logging.exception(f"Error loading file: {e}")
|
| 365 |
+
# return pd.DataFrame()
|
| 366 |
+
|
| 367 |
+
# # Function to extract the first column values
|
| 368 |
+
# def get_first_column_values(local_df):
|
| 369 |
+
# if not local_df.empty:
|
| 370 |
+
# return local_df.iloc[:, 0].tolist()
|
| 371 |
+
# else:
|
| 372 |
+
# return []
|
| 373 |
+
|
| 374 |
+
# ############################################################################################################
|
| 375 |
+
# # Prepare terms (no user file uploader anymore—only config.default_terms_csv)
|
| 376 |
+
|
| 377 |
+
# terms = load_terms(config.default_terms_csv)
|
| 378 |
+
# term_list = get_first_column_values(terms)
|
| 379 |
+
|
| 380 |
+
# ############################################################################################################
|
| 381 |
+
# # Term Selection and session state
|
| 382 |
+
|
| 383 |
+
# # Initialize the session state variables for selected term, context, and display messages
|
| 384 |
+
# if 'selected_term' not in st.session_state:
|
| 385 |
+
# st.session_state.selected_term = None
|
| 386 |
+
# if 'selected_context' not in st.session_state:
|
| 387 |
+
# st.session_state.selected_context = None
|
| 388 |
+
# if 'display_messages' not in st.session_state:
|
| 389 |
+
# st.session_state.display_messages = []
|
| 390 |
+
# if 'display_term' not in st.session_state:
|
| 391 |
+
# st.session_state.display_term = False
|
| 392 |
+
# if 'initial_message_displayed' not in st.session_state:
|
| 393 |
+
# st.session_state.initial_message_displayed = False
|
| 394 |
+
# if 'old_term' not in st.session_state:
|
| 395 |
+
# st.session_state.old_term = None
|
| 396 |
+
|
| 397 |
+
# # Dropdown menu for selecting a term
|
| 398 |
+
# selected_term = st.selectbox('**SELECT FROM THE DROPDOWN MENU**', term_list)
|
| 399 |
+
|
| 400 |
+
# if selected_term:
|
| 401 |
+
# # If a new term is selected, ask the user for input about that term
|
| 402 |
+
# if selected_term != st.session_state.old_term:
|
| 403 |
+
# user_message = (
|
| 404 |
+
# f"What is one thing you know about '{selected_term}'? What do you want to know about it? "
|
| 405 |
+
# "This could include a definition, examples, misconceptions, associations with other course terms, opinions, etc."
|
| 406 |
+
# )
|
| 407 |
+
# st.session_state["display_messages"].append({"role": "user", "content": user_message})
|
| 408 |
+
# st.session_state.old_term = selected_term
|
| 409 |
+
|
| 410 |
+
# selected_context = terms.loc[terms['TERM'] == selected_term, 'CONTEXT'].values[0]
|
| 411 |
+
# st.session_state.selected_term = selected_term
|
| 412 |
+
# st.session_state.selected_context = selected_context
|
| 413 |
+
# st.session_state.display_term = True
|
| 414 |
+
|
| 415 |
+
# # Build the prompt for the model
|
| 416 |
+
# updated_prompt = config.term_prompt(st.session_state.selected_term, st.session_state.selected_context, term_list)
|
| 417 |
+
|
| 418 |
+
# else:
|
| 419 |
+
# st.session_state.old_term = None
|
| 420 |
+
|
| 421 |
+
# # Display the selected term and context
|
| 422 |
+
# if st.session_state.display_term and st.session_state.selected_term:
|
| 423 |
+
# st.header(st.session_state.selected_term)
|
| 424 |
+
|
| 425 |
+
# with st.expander("INSTRUCTIONS FOR STUDENTS:"):
|
| 426 |
+
# st.markdown(config.instructions)
|
| 427 |
+
|
| 428 |
+
# ############################################################################################################
|
| 429 |
+
# # ChatGPT
|
| 430 |
+
# # Initialize the OpenAI client
|
| 431 |
+
# client = OpenAI(api_key=st.secrets["OPENAI_API_KEY"])
|
| 432 |
+
|
| 433 |
+
# # Initialize the model in session state if it doesn't exist
|
| 434 |
+
# if "openai_model" not in st.session_state:
|
| 435 |
+
# st.session_state["openai_model"] = config.ai_model
|
| 436 |
+
|
| 437 |
+
# # Ensure the system prompt is set with the latest selected term and context
|
| 438 |
+
# if st.session_state.get('selected_term') and st.session_state.get('selected_context'):
|
| 439 |
+
# updated_prompt = config.term_prompt(
|
| 440 |
+
# st.session_state.selected_term,
|
| 441 |
+
# st.session_state.selected_context,
|
| 442 |
+
# term_list
|
| 443 |
+
# )
|
| 444 |
+
# if st.session_state.display_messages:
|
| 445 |
+
# st.session_state.display_messages[0]["content"] = updated_prompt
|
| 446 |
+
# else:
|
| 447 |
+
# st.session_state.display_messages = [{"role": "system", "content": updated_prompt}]
|
| 448 |
+
|
| 449 |
+
# # Chat input
|
| 450 |
+
# prompt = st.chat_input("What do you know? What do you want to know?")
|
| 451 |
+
|
| 452 |
+
# # Input for new messages
|
| 453 |
+
# if prompt:
|
| 454 |
+
# # If no initial context in display_messages, add it
|
| 455 |
+
# if not st.session_state["display_messages"]:
|
| 456 |
+
# st.session_state["display_messages"].append({"role": "system", "content": updated_prompt})
|
| 457 |
+
# st.session_state["display_messages"].append({"role": "user", "content": prompt})
|
| 458 |
+
|
| 459 |
+
# # Function to reset all chat-related session state
|
| 460 |
+
# def reset_chat_history():
|
| 461 |
+
# st.session_state["display_messages"] = []
|
| 462 |
+
# if 'selected_term' in st.session_state:
|
| 463 |
+
# st.session_state.selected_term = None
|
| 464 |
+
# if 'selected_context' in st.session_state:
|
| 465 |
+
# st.session_state.selected_context = None
|
| 466 |
+
# if 'display_term' in st.session_state:
|
| 467 |
+
# st.session_state.display_term = False
|
| 468 |
+
# st.rerun()
|
| 469 |
+
|
| 470 |
+
# ############################################################################################################
|
| 471 |
+
# # Main chat container
|
| 472 |
+
|
| 473 |
+
# with st.container():
|
| 474 |
+
# # Display chat history in reverse order
|
| 475 |
+
# for message in st.session_state["display_messages"][1:]:
|
| 476 |
+
# if message["role"] == "user":
|
| 477 |
+
# with st.chat_message("user"):
|
| 478 |
+
# st.markdown(message["content"])
|
| 479 |
+
# else:
|
| 480 |
+
# with st.chat_message("assistant"):
|
| 481 |
+
# st.markdown(message["content"])
|
| 482 |
+
|
| 483 |
+
# # Generate assistant response
|
| 484 |
+
# if prompt:
|
| 485 |
+
# with st.chat_message("assistant"):
|
| 486 |
+
# try:
|
| 487 |
+
# stream = client.chat.completions.create(
|
| 488 |
+
# model=st.session_state["openai_model"],
|
| 489 |
+
# messages=[
|
| 490 |
+
# {"role": m["role"], "content": m["content"]}
|
| 491 |
+
# for m in st.session_state["display_messages"]
|
| 492 |
+
# ],
|
| 493 |
+
# stream=True,
|
| 494 |
+
# temperature=config.temperature,
|
| 495 |
+
# max_tokens=config.max_tokens,
|
| 496 |
+
# frequency_penalty=config.frequency_penalty,
|
| 497 |
+
# presence_penalty=config.presence_penalty,
|
| 498 |
+
# )
|
| 499 |
+
# response = st.write_stream(stream)
|
| 500 |
+
# st.session_state["display_messages"].append({"role": "assistant", "content": response})
|
| 501 |
+
# logging.info(f"User prompt: {prompt}")
|
| 502 |
+
# logging.info(f"Assistant response: {response}")
|
| 503 |
+
# except Exception as e:
|
| 504 |
+
# st.error(f"An error occurred: {str(e)}")
|
| 505 |
+
# logging.exception(f"Error generating response: {e}")
|
| 506 |
+
|
| 507 |
+
# # Clear chat history button
|
| 508 |
+
# if st.button("Clear Chat History"):
|
| 509 |
+
# reset_chat_history()
|
| 510 |
+
# logging.info("Chat history cleared")
|
| 511 |
+
|
| 512 |
+
# st.markdown(config.warning_message, unsafe_allow_html=True)
|
| 513 |
+
|
| 514 |
+
# ############################################################################################################
|
| 515 |
+
# # Resources and About Sections in the Sidebar
|
| 516 |
+
|
| 517 |
+
# st.sidebar.title("Resources")
|
| 518 |
+
|
| 519 |
+
# for resource in config.resources:
|
| 520 |
+
# with st.sidebar:
|
| 521 |
+
# with st.expander(resource["title"]):
|
| 522 |
+
# st.markdown(f"Description: {resource['description']}")
|
| 523 |
+
# if "url" in resource:
|
| 524 |
+
# st.markdown(f"[{resource['title']}]({resource['url']})")
|
| 525 |
+
# if "file_path" in resource:
|
| 526 |
+
# file_path = resource["file_path"]
|
| 527 |
+
# if os.path.exists(file_path):
|
| 528 |
+
# with open(file_path, "rb") as file:
|
| 529 |
+
# file_bytes = file.read()
|
| 530 |
+
# with st.spinner(f"Loading {resource['title']}..."):
|
| 531 |
+
# st.download_button(
|
| 532 |
+
# label=resource["title"],
|
| 533 |
+
# data=file_bytes,
|
| 534 |
+
# file_name=os.path.basename(file_path),
|
| 535 |
+
# mime="application/octet-stream",
|
| 536 |
+
# help=resource["description"],
|
| 537 |
+
# )
|
| 538 |
+
# else:
|
| 539 |
+
# st.warning(f"File not found: {file_path}")
|
| 540 |
+
|
| 541 |
+
# with st.sidebar:
|
| 542 |
+
# st.markdown("---")
|
| 543 |
+
# st.title("About")
|
| 544 |
+
# st.markdown(config.app_creation_message, unsafe_allow_html=True)
|
| 545 |
+
# st.markdown(config.app_repo_license_message, unsafe_allow_html=True)
|
| 546 |
+
|