So in my chat bot that I’m creating, I’ve also made it so that when the AI replies to the user it generates some potential prompts in the form of buttons that looks like the screenshot
When I click on one of the prompts, I want all the buttons to disappear and have it start generating the response to that prompt. But right now the buttons remain and the the response is generated after the selected button.
My Problem: I just want the buttons to disappear on click, I dont want them to fade as well, I want it to be seamless. I’ve tried using radio buttons and they seemed worse. Another solution could be : When one of the prompt buttons are clicked, the text is set to the chat_input and then the buttons are disappeared.
This is the code im using :
if prompt := st.chat_input("Type your question here..."):
st.session_state.messages.append({"role": "user", "content": prompt})
with st.chat_message("user"):
st.markdown(f'<div class="user-message">{prompt}</div>', unsafe_allow_html=True)
with st.chat_message("assistant"):
stream = client.chat.completions.create(
model=st.session_state["openai_model"],
messages=[system_message, user_message],
stream=True,
temperature=0.1
)
response = st.write_stream(stream)
st.session_state.messages.append({"role": "assistant", "content": response})
st.session_state.response_ready = True
if st.session_state.response_ready:
option_stream = client.chat.completions.create(
model=st.session_state["openai_model"],
messages=[response_generation_message, response_prompt],
stream=False,
max_tokens=100,
temperature=0.1
)
raw_response = option_stream.choices[0].message.content.strip()
response_options = [
line.strip()[3:].strip()
for line in raw_response.split("\n")
if line.strip() and line.strip()[0].isdigit() and line.strip()[1] == "."
]
if response_options:
st.session_state.response_options = response_options
else:
st.session_state.response_options = ["Failed to generate valid options. Please try again."]
st.session_state.response_ready = False
if st.session_state.response_options:
button_container = st.container()
with button_container:
for idx, option in enumerate(st.session_state.response_options):
if st.button(option, key=f"response_option_{idx}"):
button_container.empty()
st.session_state.messages.append({"role": "user", "content": option})
with st.chat_message("user"):
st.markdown(f'<div class="user-message">{option}</div>', unsafe_allow_html=True)
with st.chat_message("assistant"):
stream = client.chat.completions.create(
model=st.session_state["openai_model"],
messages=[system_message, option_message],
stream=True,
temperature=0.1
)
option_response = st.write_stream(stream)
st.session_state.messages.append({"role": "assistant", "content": option_response})
st.session_state.response_ready = True
st.experimental_rerun()
We can use custom CSS to hide the suggestion buttons while the bot is generating a response. After that, we will trigger st.rerun()to make sure all elements are organized on screen and remove the custom CSS.
import streamlit as st
import asyncio
# Initialize session state for chat messages
if 'chat_messages' not in st.session_state:
st.session_state.chat_messages = []
# Render the chat messages
for message in st.session_state.chat_messages:
with st.chat_message(message['role']):
st.markdown(message['content'])
# Hide the prompt suggestions buttons
def hide_buttons():
st.markdown(
"""
<style>
button[data-testid="stBaseButton-secondary"] {
display: none;
}
</style>
""",
unsafe_allow_html=True,
)
# Mock async function to generate a response
async def generate_response():
hide_buttons()
await asyncio.sleep(2) # Add a 2-second async delay
return "This is a demo response"
# Handling user input through chat input
if prompt := st.chat_input("Type your message here..."):
st.session_state.chat_messages.append({"role": "user", "content": prompt})
with st.chat_message("user"):
st.markdown(prompt)
response = asyncio.run(generate_response())
st.session_state.chat_messages.append({"role": "assistant", "content": response})
# Trigger a rerun to update the chat messages
st.rerun()
# Prompt suggestions
prompt_suggestions = [
"What is the weather today?",
"What is the time now?",
"How are you doing?",
"What is the weather tomorrow?"
]
# Handling prompt suggestions
for suggestion in prompt_suggestions:
if st.button(suggestion):
st.session_state.chat_messages.append({"role": "user", "content": suggestion})
with st.chat_message("user"):
st.markdown(suggestion)
response = asyncio.run(generate_response())
st.session_state.chat_messages.append({"role": "assistant", "content": response})
# Trigger a rerun to update the chat messages
st.rerun()
Hi, So I tried adding your custom css as a hide_buttons function like this:
def hide_buttons():
st.markdown(
"""
<style>
button[data-testid="stBaseButton-secondary"] {
display: none;
}
</style>
""",
unsafe_allow_html=True,
)
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.markdown(message["content"], unsafe_allow_html=True)
if st.session_state.response_options:
button_container = st.container()
with button_container:
for idx, option in enumerate(st.session_state.response_options):
if st.button(option, key=f"response_option_{idx}"):
hide_buttons()
st.session_state.messages.append({"role": "user", "content": option})
with st.chat_message("user"):
st.markdown(f'<div class="user-message">{option}</div>', unsafe_allow_html=True)
with st.chat_message("assistant"):
stream = client.chat.completions.create(
model=st.session_state["openai_model"],
messages=[system_message, option_message],
stream=True,
temperature=0.1
)
option_response = st.write_stream(stream)
st.session_state.messages.append({"role": "assistant", "content": option_response})
st.session_state.response_ready = True
st.rerun()
But as you can see in these attached screenshots, I would like if it the selected button also disappears right now all the buttons till the selected button stays while the buttons below disappears
And also when I enter a new message myself in the chat_input it displays that weird fade to grey you can see in the screenshot. After a few seconds it does the rerun and it disappears but it lingers for a while
On my end, your code is working great! It seems like the problem might be coming from the custom CSS you’re using.
import streamlit as st
import openai
import dotenv
import os
dotenv.load_dotenv()
client = openai.Client(api_key=os.getenv("OPENAI_API_KEY"))
# Initialize session state variables if they don't exist
if "messages" not in st.session_state:
st.session_state.messages = []
if "response_options" not in st.session_state:
st.session_state.response_options = [
'What is the meaning of life?',
'What is the capital of France?',
'What is the largest planet in the solar system?',
]
if "openai_model" not in st.session_state:
st.session_state.openai_model = "gpt-4o-mini"
def hide_buttons():
st.markdown(
"""
<style>
button[data-testid="stBaseButton-secondary"] {
display: none;
}
</style>
""",
unsafe_allow_html=True,
)
# Display chat messages
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.markdown(message["content"], unsafe_allow_html=True)
# Display response options as buttons
if st.session_state.response_options:
button_container = st.container()
with button_container:
for idx, option in enumerate(st.session_state.response_options):
if st.button(option, key=f"response_option_{idx}"):
hide_buttons()
st.session_state.messages.append({"role": "user", "content": option})
with st.chat_message("user"):
st.markdown(f'<div class="user-message">{option}</div>', unsafe_allow_html=True)
# Define system_message and option_message
system_message = {"role": "system", "content": "You are a helpful assistant."}
option_message = {"role": "user", "content": option}
with st.chat_message("assistant"):
stream = client.chat.completions.create(
model=st.session_state["openai_model"],
messages=[system_message, option_message],
stream=True,
temperature=0.1
)
option_response = st.write_stream(stream)
st.session_state.messages.append({"role": "assistant", "content": option_response})
st.session_state.response_ready = True
st.rerun()
if prompt_input := st.chat_input("Enter a message..."):
hide_buttons()
st.session_state.messages.append({"role": "user", "content": prompt_input})
with st.chat_message("user"):
st.markdown(f'<div class="user-message">{prompt_input}</div>', unsafe_allow_html=True)
# Define system_message and user_message
system_message = {"role": "system", "content": "You are a helpful assistant."}
user_message = {"role": "user", "content": prompt_input}
with st.chat_message("assistant"):
stream = client.chat.completions.create(
model=st.session_state["openai_model"],
messages=[system_message, user_message],
stream=True,
temperature=0.1
)
response = st.write_stream(stream)
st.session_state.messages.append({"role": "assistant", "content": response})
st.rerun()
Hi ! Yeah your screen recording is exactly how I pictured it, I think maybe its not seamless for me since I’m using AI to generate the response options which is then displayed as those buttons. Is it possible if you could try that and let me know how it works for you?
Basically Im using one prompt/OpenAI API call for the chatting and a separate one for the response option buttons specifically BASED ON THE AI CHATBOT’s PREVIOUS MESSAGE
So if the AI responded with something about Mumbai, the response options would be Mumbai related
Thanks for stopping by! We use cookies to help us understand how you interact with our website.
By clicking “Accept all”, you consent to our use of cookies. For more information, please see our privacy policy.
Cookie settings
Strictly necessary cookies
These cookies are necessary for the website to function and cannot be switched off. They are usually only set in response to actions made by you which amount to a request for services, such as setting your privacy preferences, logging in or filling in forms.
Performance cookies
These cookies allow us to count visits and traffic sources so we can measure and improve the performance of our site. They help us understand how visitors move around the site and which pages are most frequently visited.
Functional cookies
These cookies are used to record your choices and settings, maintain your preferences over time and recognize you when you return to our website. These cookies help us to personalize our content for you and remember your preferences.
Targeting cookies
These cookies may be deployed to our site by our advertising partners to build a profile of your interest and provide you with content that is relevant to you, including showing you relevant ads on other websites.