import streamlit as st
import random
import time
st.title("Simple chat")
# Initialize chat history
if "messages" not in st.session_state:
st.session_state.messages = []
# Display chat messages from history on app rerun
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.markdown(message["content"])
# Accept user input
if prompt := st.chat_input("What is up?"):
# Add user message to chat history
st.session_state.messages.append({"role": "user", "content": prompt})
# Display user message in chat message container
with st.chat_message("user"):
st.markdown(prompt)
# Display assistant response in chat message container
with st.chat_message("assistant"):
message_placeholder = st.empty()
full_response = ""
assistant_response = random.choice(
[
"Hello there! How can I assist you today?",
"Hi, human! Is there anything I can help you with?",
"Do you need help?",
]
)
# Simulate stream of response with milliseconds delay
for chunk in assistant_response.split():
full_response += chunk + " "
time.sleep(0.05)
# Add a blinking cursor to simulate typing
message_placeholder.markdown(full_response + "▌")
message_placeholder.markdown(full_response)
# Add assistant response to chat history
st.session_state.messages.append({"role": "assistant", "content": full_response})
If applicable, please provide the steps we should take to reproduce the error or specified behavior.
Expected behavior:
The questions and answers should be preserved if I refresh the page. Also if I refresh the page while an answer is being generated, the chat box should be blocked so I have to wait until the current answer is generated.
Thanks for posting! So st.session_state is designed to maintain the state across reruns of the app within the same browser session. When you refresh the app, it starts a new session and that’s why the content refreshes as well. There’s no browser/cookie-based storage yet. Also, if you refresh while the assistant is “typing,” the message won’t complete since the state has been reset.
You can consider connecting to a database and saving the responses and prompts there then calling them upon refreshes.
Session State always resets on page refresh. You will need to use a simple database to store the resoponses.
Behavior of blocking further chat when one response / continuing on response is kinda complex.
Implementing on @tonykip 's explanation:
I have used tinydb here. (do pip install tinydb to resolve missing dependency)
import streamlit as st
import random
import time
from tinydb import TinyDB
# Initialize chat history
db = TinyDB('chat_history.json')
st.title("Simple chat")
# Initialize chat history from previous sessions
chat_history = db.all()
# Display chat messages from history on app rerun
for message in chat_history:
with st.chat_message(message["role"]):
st.markdown(message["content"])
# Disable text input when assistant is responding
if "disabled" not in st.session_state:
st.session_state["disabled"] = False
# Toggle disabled state
def disable_toggle():
st.session_state["disabled"] = not(st.session_state["disabled"])
# Button to to test disable
if st.button('toggle'):
disable_toggle()
# Accept user input if assistant is not responding
# if not st.session_state.disabled: # Check if the text input is not disabled
prompt = st.chat_input("What is up?", disabled=st.session_state["disabled"])
if prompt:
# Add user message to chat history
user_message = {"role": "user", "content": prompt}
chat_history.append(user_message)
db.insert(user_message)
# Display user message in chat message container
with st.chat_message("user"):
st.markdown(prompt)
# Simulate assistant response
with st.chat_message("assistant"):
message_placeholder = st.empty()
full_response = ""
assistant_response = random.choice([
"Hello there! How can I assist you today?",
"Hi, human! Is there anything I can help you with?",
"Do you need help?",
])
for chunk in assistant_response.split():
full_response += chunk + " "
time.sleep(0.05)
# Add a blinking cursor to simulate typing
message_placeholder.markdown(full_response + "▌")
message_placeholder.markdown(full_response)
# Add assistant response to chat history
assistant_message = {"role": "assistant", "content": full_response}
chat_history.append(assistant_message)
db.insert(assistant_message)
# Reset chat history button
if len(db.all()) > 0:
# Show button if Chat history not empty
if st.button("Reset Chat"):
# Delete all entries in Database
db.truncate()
# Reload Page
st.experimental_rerun()
Hi @tonykip, thanks for replying. Is there a good way to check if the page was refreshed? I could not find a function or something that is made for that sadly.
There’s no specific function to check if was refreshed. The refresh is related to manually hitting the refresh/reload button on your browser which creates a new session and wipes the session state.