I’m building a chatbot application for my company. I’m using streamlit 1.39.0 version. I’m trying to capture user feedback, so I implemented below code from “st.feedback - Streamlit Docs” after AI response, but after selecting a response I’m still getting None in ‘selected’ field.
sentiment_mapping = [“:material/thumb_down:”, “:material/thumb_up:”]
selected = st.feedback(“thumbs”)
if selected is not None:
st.markdown(f"You selected: {sentiment_mapping[selected]}")
Can you share a bit more context about how you have st.feedback within your chat app? Since the code works by itself as shown in the example within docs, there should be something else that’s impacting the behavior.
I’m able to see the thumps-up and down after AI response, but it’s immediately going to the else condition st.markdown(f"You did not select"), which mean it’s not waiting for user to choose the feedback. Also, upon choosing a feedback, the thumbs up and down are gone without capturing the feedback in ‘selected’ variable.
from dotenv import load_dotenv
from langchain_core.messages import AIMessage, HumanMessage
import streamlit as st
import requests
import os
import logging
# Claude API endpoint and key
url = llm-url
api_key = os.getenv("key")
# Function to handle API call and response formatting
def get_response(api_name, api_inputs, user_query, user_role, chat_history):
fetch_function = API_CONFIG[api_name]["fetch_function"]
# Pass the `api_name` (config_key) as the first argument to the fetch function
api_data = fetch_function(api_name, **api_inputs)
# Define the template and prompt
template = """
template details goes here"""
formatted_prompt = template.format(api_data=api_data, question=user_query, role=user_role)
model = "model-name"
body = {
"model": model,
"messages": [
{"role": "system",
"content": "You are a helpful assistant that responds to user queries based on provided API data."},
{"role": "user", "content": formatted_prompt}
]
}
# Make the API call to Claude
response = requests.post(url, json=body, headers={
"Content-Type": "application/json",
"Authorization": api_key,
})
def handle_ai_response(response):
"""Function to handle displaying AI response and feedback."""
with st.chat_message("AI", avatar=ai_avatar):
st.markdown(response) # Display the AI response
st.session_state.chat_history.append(AIMessage(content=response)) # Add AI response to chat history
sentiment_mapping = [":material/thumb_down:", ":material/thumb_up:"]
selected = st.feedback("thumbs")
if selected is not None:
st.markdown(f"You selected: {sentiment_mapping[selected]}")
else:
st.markdown(f"You did not select")
# Define paths to the avatar images
human_avatar = "images/human.svg"
ai_avatar = "images/ai.svg"
for message in st.session_state.chat_history:
if isinstance(message, AIMessage):
with st.chat_message("AI", avatar=ai_avatar):
st.markdown(message.content)
elif isinstance(message, HumanMessage):
with st.chat_message("Human", avatar=human_avatar):
st.markdown(f"You: {message.content}")
# Input through chat box
user_query = st.chat_input("Type a message...")
if user_query and user_query.strip():
st.session_state.chat_history.append(HumanMessage(content=user_query))
with st.chat_message("Human", avatar=human_avatar):
st.markdown(user_query)
# Call the refactored function to handle AI response
response = get_response(selected_api, api_inputs, user_query, selected_role, st.session_state.chat_history)
handle_ai_response(response)
Please can you edit your post so that your code is in a code block? Use a triple backtick at the beginning and end, or use the <> icon in the editor toolbar.
Just a quick hint from what I can gather from the unformatted code. (Just a gut guess since I can’t properly see your whitespace yet. )
You’ll likely want to handle feedback separately from the new response.
You have your app ready for user input. User submits a response → Rerun.
The AI response is handled in handle_ai_resonse which adds the response to history and shows the feedback widget (which has value None). If you click the feedback widget → Rerun.
On the rerun where you want to get the value of the feedback, you aren’t in the handle_ai_response function anymore.
Looking at your code, I think my initial guess is correct: as soon as you click the feedback, the app reruns and now that last response becomes part of the history and I expect the feedback widget to disappear. What are you wanting to do with the feedback information when you receive it? Are you wanting to save it and show it in the history for every AI response in the history, or something else?
Here’s a toy example that saves the last user + AI message with feedback to a file. If a user doesn’t give feedback on some response, it’s skipped.
If you want to save then entire conversation, you could write all messages to the file and just append the feedback when given. You could also add the feedback to the message dict in Session State then write the whole conversation to a file when done. If you need to persist the feedback widgets in the conversation throughout, you’ll need to introduce keys (such as the numerical position of the message in the history) and maybe add a third key to the AI messages (“role”,“content”,“feedback”).
import streamlit as st
def bot():
yield "Hi"
if "messages" not in st.session_state:
st.session_state.messages = []
if "get_feedback" not in st.session_state:
st.session_state.get_feedback = False
def save_feedback():
with open("myfile.txt", "a") as f:
f.write(str(st.session_state.messages[-2]["role"])+"\n")
f.write(str(st.session_state.messages[-2]["content"])+"\n")
f.write(str(st.session_state.messages[-1]["role"])+"\n")
f.write(str(st.session_state.messages[-1]["content"])+"\n")
f.write(str(st.session_state.feedback)+"\n")
st.session_state.get_feedback = False
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.markdown(message["content"])
if prompt := st.chat_input("Say something"):
st.session_state.messages.append({"role": "user", "content": prompt})
with st.chat_message("user"):
st.markdown(prompt)
with st.chat_message("assistant"):
stream = bot() # Shorthand for some AI streamed
response = st.write_stream(stream)
st.session_state.messages.append({"role": "assistant", "content": response})
st.session_state.get_feedback = True
if st.session_state.get_feedback:
st.feedback("thumbs", key="feedback", on_change=save_feedback)
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.