Chainlit / chainlit

Build Conversational AI in minutes ⚡️
https://docs.chainlit.io
Apache License 2.0
6.07k stars 776 forks source link

Change Thread Name #1097

Open trinhkiet0105 opened 1 week ago

trinhkiet0105 commented 1 week ago

I try to change thread Name on the chat UI but know how to

The thread name is default to take the first User message as the thread name. I want to customize thread name after the first assistant response (like chatGPT)

AidanShipperley commented 1 week ago

I'd also love to know if there is an actual way to do this properly.

I was able to find a way to manually do this, however it doesn't update the UI until the user refreshes the page. Regardless, it may still be useful to you or the maintainers:

Make a Function to Create Chat Title

async def generate_conv_summary(conv_messages):

    client = AsyncOpenAI()
    conv = ""
    for message in conv_messages:
        if message["role"] == "user":
            conv += f"User: {message['content']}\n"
        elif message["role"] == "assistant":
            conv += f"Assistant: {message['content']}\n"

    messages = [
        {"role": "system",
         "content": "Act as a conversation summarization engine designed to create a short title for a conversation between a user and an AI assistant. Given a conversation, you will generate a title for that conversation in 3 (three) words or less. The title should be a concise summary of the conversation, capturing the main topic or theme of the conversation."},
        {"role": "system", "content": conv}
    ]

    stream = await client.chat.completions.create(
            messages=messages, stream=True, model="gpt-4o"
    )

    return stream

Add Functionality to Main Function

# import chainlit.data as cl_data
@cl.on_message
async def main(message: cl.Message):

    message_history = cl.user_session.get("message_history")
    # Custom code to identify if this is the first message in a thread
    first_msg = False
    if len([msg for msg in message_history if msg.get('role') == 'user']) == 1:
        first_msg = True

    # Generate and give msg to user as usual
    # ...
    # message_history.append({"role": "assistant", "content": generated_msg.content})
    ###

    # Once assistant message is generated, generate chat title and update the thread name
    if first_msg:
        chat_title = ""
        conv_summary_streamer = await generate_conv_summary(message_history)
        async for part in conv_summary_streamer:
            if token := part.choices[0].delta.content or "":
                chat_title += token

        chat_title = chat_title.title().replace(".", "")
        await cl_data._data_layer.update_thread(message.thread_id, name=chat_title)

Hopefully this helps, I would love to know of a way to update the thread name and instantly have it render onto the UI.

trinhkiet0105 commented 1 week ago

I'd also love to know if there is an actual way to do this properly.

I was able to find a way to manually do this, however it doesn't update the UI until the user refreshes the page. Regardless, it may still be useful to you or the maintainers:

Make a Function to Create Chat Title

async def generate_conv_summary(conv_messages):

    client = AsyncOpenAI()
    conv = ""
    for message in conv_messages:
        if message["role"] == "user":
            conv += f"User: {message['content']}\n"
        elif message["role"] == "assistant":
            conv += f"Assistant: {message['content']}\n"

    messages = [
        {"role": "system",
         "content": "Act as a conversation summarization engine designed to create a short title for a conversation between a user and an AI assistant. Given a conversation, you will generate a title for that conversation in 3 (three) words or less. The title should be a concise summary of the conversation, capturing the main topic or theme of the conversation."},
        {"role": "system", "content": conv}
    ]

    stream = await client.chat.completions.create(
            messages=messages, stream=True, model="gpt-4o"
    )

    return stream

Add Functionality to Main Function

# import chainlit.data as cl_data
@cl.on_message
async def main(message: cl.Message):

    message_history = cl.user_session.get("message_history")
    # Custom code to identify if this is the first message in a thread
    first_msg = False
    if len([msg for msg in message_history if msg.get('role') == 'user']) == 1:
        first_msg = True

    # Generate and give msg to user as usual
    # ...
    # message_history.append({"role": "assistant", "content": generated_msg.content})
    ###

    # Once assistant message is generated, generate chat title and update the thread name
    if first_msg:
        chat_title = ""
        conv_summary_streamer = await generate_conv_summary(message_history)
        async for part in conv_summary_streamer:
            if token := part.choices[0].delta.content or "":
                chat_title += token

        chat_title = chat_title.title().replace(".", "")
        await cl_data._data_layer.update_thread(message.thread_id, name=chat_title)

Hopefully this helps, I would love to know of a way to update the thread name and instantly have it render onto the UI.

love the way how you done it, I read the documents said that chainlit is auto refresh on first message (for the change of the URL has to include the thread id) so I figured it out This code work for me to update after the first reponse :

from literalai import LiteralClient 
@cl.on_message 
async def main(message: cl.Message):
     #response and do something ...
      client = LiteralClient(api_key=os.getenv("LITERAL_API_KEY"))
      client.api.update_thread(id = thread_id, participant_id= participantId, name = topic)

note that participantId is the user id and the topic is the desired thread name