Summary
If there is additional processing time between the st.chat_input() method call and the st.chat_message() method call, there’s an unexpected full-scrolling effect during the screen refresh.
Steps to reproduce
This is taken from the conversational app example, with a minor change. I add a brief pause (0.05s) just before echoing the assistant’s echo response.
Code snippet:
import streamlit as st
import time
st.title("Echo Bot")
# 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"])
# React to user input
if prompt := st.chat_input("What is up?"):
# Display user message in chat message container
st.chat_message("user").markdown(prompt)
# Add user message to chat history
st.session_state.messages.append({"role": "user", "content": prompt})
# simulate some type of processing time needed
time.sleep(0.05)
response = f"Echo: {prompt}"
# Display assistant response in chat message container
with st.chat_message("assistant"):
st.markdown(response)
# Add assistant response to chat history
st.session_state.messages.append({"role": "assistant", "content": response})
If you run this as an app, and then send multiple inputs, at some point you’ll see the screen refresh, start at the top, and scroll all the way down. I use the following input, and it takes 3 submissions for the effect to occur. It doesn’t happen every submission. I also notice that the active focus shifts off the input box at the same time.
if prompt := st.chat_input("Seek knowledge..."): # Display user message in chat message container st.chat_message("user").markdown(prompt) # Add user message to chat history st.session_state.messages.append({"role": "user", "content": prompt}
Expected behavior:
I expect the chat_message container to scroll from its current place, down to accommodate the new input & response. And the active focus should stay on the input box.
This is the observed behavior when there is not a pause added.
Actual behavior:
Instead, after some number of input submissions (e.g., 3 or 4), you’ll see the screen refresh, start at the top, and scroll all the way down. The active focus also shifts off the input box.
Debug info
- Streamlit version: 1.26.0
- Python version: 3.10.10
- Using pip
- OS version: Debian 11
- Browser version: I’ve experienced this on 116.0.5845.190 (Official Build) (64-bit) and Microsoft Edge 115.0.1901.200 (Official build) (64-bit)