Chainlit / chainlit

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

Teams Integration bug #1426

Open cesi08 opened 1 month ago

cesi08 commented 1 month ago

I created a chainlit azure webapp with python 3.11, integrating a microsoft teams bot, as explained in the documentation Teams - Chainlit. Is there a way i can override the default behaviour of /chainlit/teams/app.py script present in the chainlit library, in order to maintain the chat session in teams conversation? Currently, every time a user writes a new message, the chat is reloaded and a new thread is started. I need to implement the memory feature in the teams chat. I'm using

chainlit==1.2.0 botbuilder-core==4.16.2 langchain==0.2.16

the model that I'm using is gpt-3.5 turbo in Azure.

dosubot[bot] commented 1 month ago

Hello @cesi08! I'm here to help you with any bugs, questions, or contributions you have.

To maintain chat sessions in a Microsoft Teams conversation using Chainlit, you can modify the process_teams_message function in the /chainlit/teams/app.py script. Here's how you can do it:

  1. Use a consistent thread_id and session_id for the conversation to ensure session persistence.

  2. Avoid deleting the session at the end of the function to keep it active for subsequent messages.

Here's a modified version of the process_teams_message function:

async def process_teams_message(
    turn_context: TurnContext,
    thread_name: str,
):
    user = await get_user(turn_context.activity.from_property)

    # Use a consistent thread_id for the conversation
    thread_id = str(
        uuid.uuid5(
            uuid.NAMESPACE_DNS,
            str(turn_context.activity.conversation.id)
        )
    )

    text = clean_content(turn_context.activity)
    teams_files = turn_context.activity.attachments

    # Use a consistent session_id for the conversation
    session_id = f"session_{thread_id}"

    # Check if session already exists, otherwise create a new one
    session = HTTPSession(
        id=session_id,
        thread_id=thread_id,
        user=user,
        client_type="teams",
    )

    ctx = init_teams_context(
        session=session,
        turn_context=turn_context,
    )

    file_elements = await download_teams_files(session, teams_files)

    if on_chat_start := config.code.on_chat_start:
        await on_chat_start()

    msg = Message(
        content=text,
        elements=file_elements,
        type="user_message",
        author=user.metadata.get("name"),
    )

    await msg.send()

    if on_message := config.code.on_message:
        await on_message(msg)

    if on_chat_end := config.code.on_chat_end:
        await on_chat_end()

    if data_layer := get_data_layer():
        if isinstance(user, PersistedUser):
            try:
                await data_layer.update_thread(
                    thread_id=thread_id,
                    name=thread_name,
                    metadata=ctx.session.to_persistable(),
                    user_id=user.id,
                )
            except Exception as e:
                logger.error(f"Error updating thread: {e}")

    # Do not delete the session to maintain it
    # ctx.session.delete()

This modification ensures that the session is maintained across messages by using a consistent session_id and thread_id for the conversation [1].

To continue talking to Dosu, mention @dosu.

cesi08 commented 1 month ago

@dosu If I deploy the web app with this command in a terminal `az webapp up -g %res_group% --name %app_name% --sku B1 --location francecentral --runtime PYTHON:3.11 --logs

` the /chainlit/teams/app.py script is part of the chainlit library, so even if I modify it locally, when I delloy on azure webapp the chainlit library will be reinstalled, and the script will return as the original

dosubot[bot] commented 1 month ago

To override or extend the functionality of a script in the Chainlit library without modifying the library directly, you can create a plugin. Here's how:

  1. Create a New Plugin Directory: In your project, create a plugins folder and add a new directory for your plugin.

  2. Define Functions: Inside this directory, create a functions.py file. Define the functions you want to override or extend.

  3. Configure the Plugin: Add a config.json file in the same directory with the following content:

    {
        "enabled": true
    }
  4. Enable the Plugin: Ensure the enabled field is set to true so the functions are imported and used.

This approach allows you to maintain custom behavior even after deploying to Azure, as your plugin will be part of your project and not overwritten by library updates [1].

To continue talking to Dosu, mention @dosu.

cesi08 commented 1 month ago

@dosu

in my case it's not working, I get the following error chainlit.context.ChainlitContextException: Chainlit context not found as in my on_message I am using a LangChain AgentExecutor. I really need to override the behavior of teams/app.py so that the chat is not reloaded every time a user writes a new message

dosubot[bot] commented 1 month ago

To address the ChainlitContextException and ensure the chat session is maintained, you can try the following approach:

  1. Custom Script: Instead of modifying the library directly, create a custom script in your project that mimics the behavior of teams/app.py but with your desired changes.

  2. Consistent Context: Ensure that the ChainlitContext is consistently initialized and maintained across messages. You can do this by using a consistent session_id and thread_id as previously mentioned.

  3. AgentExecutor Handling: Make sure the LangChain AgentExecutor is correctly integrated. Retrieve it from the session and use it to process messages:

    agent = cl.user_session.get("agent")  # Ensure this is set correctly
    res = await cl.make_async(agent.run)(
       input=message.content, callbacks=[cl.LangchainCallbackHandler()]
    )
    await cl.Message(content=res).send()
  4. Deployment: Deploy your custom script instead of relying on the default teams/app.py. This way, your changes will persist even after deployment.

By creating a custom script and ensuring the context is properly managed, you should be able to maintain the chat session without reloading.

To continue talking to Dosu, mention @dosu.