Chat history in st.chat_input()

Chat History in st.chat_input

I am looking for a way to implement chat history in st.chat_input function. Something similar to chat input in chainlit chat (where there is a button on the left-hand side to see previous entries) or a terminal where user can find last entries by using arrows on the keybord.

Is there a way to get this functionality? If its not currently available, I would be happy to have a look on how to implement it, but would need some initial ideas from the community :slight_smile:


Hi there!

You can use a session state variable to keep track of the chats. Here is a ver simple example of it.

import streamlit as st
import string
import random

def randon_string() -> str:
    return "".join(random.choices(string.ascii_uppercase + string.digits, k=10))

def chat_actions():
        {"role": "user", "content": st.session_state["chat_input"]},

            "role": "assistant",
            "content": randon_string(),
        },  # This can be replaced with your chat response logic

if "chat_history" not in st.session_state:
    st.session_state["chat_history"] = []

st.chat_input("Enter your message", on_submit=chat_actions, key="chat_input")

for i in st.session_state["chat_history"]:
    with st.chat_message(name=i["role"]):


Thank you for the reply and the code example. I am after a slightly different functionality though.

For example, in Chainlit (attached screenshot) there is a button on the left hand side of the chat input:

That button gives history of previous commands. I would like something similar in st.chat_input().

For example, something like:

if prompt := st.chat_input(placeholder="", num_previous_inputs=10):

and this would result in the user being able to easily re-enter 10 previous commands (like in Chainlit). It does not have to be an actual button in the chat input, it might be easier to navigate just using arrows on the keyboard (like a linux terminal).

Would there be a way to implement this as part of st._chat_input?


This would be awesome. Same requirement here.

One could solve this with callbacks and input capture outside of Streamlit. Seems like a hacky way versus a native implementation.

The โ€˜let me ask a slightly different variation of my prior promptโ€™ use case comes up frequently in LLMs.

1 Like

Since the chat history can be saved in session state in a dictionary or list. You can use a number_input widget to specify the slice of the list or dictionary you want to render. Thats how I did on my last implementation and works pretty well.

For example I have a number_input widget:

        "Show last messages:",

Then use it on my render chat function.


which invokes โ†’

def render_chat_history(show_last: int):
    if len(st.session_state["chat_history"]) > show_last:
        for i in st.session_state["chat_history"][-show_last:]:
            with st.chat_message(name="user"):
            with st.chat_message(name="assistant"):
        for i in st.session_state["chat_history"]:
            with st.chat_message(name="user"):
            with st.chat_message(name="assistant"):

In my case, a message is the combination of prompt and response since I save them in that manner in an ordered list.

Hope this helps.

Hello Carlos,

Thank you for sharing the code, but this is not what we are after. Your code displays conversation history on the UI (similarly to the first code snippet at the top of the thread). However, we are after the โ€œlinux terminaโ€ style chat history in chat_input widget. Iโ€™ve opened Github issue as well for more context: Chat History in `st.chat_input` widget ยท Issue #7107 ยท streamlit/streamlit ยท GitHub

Perhaps you know how could I go about implementing this?

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.