Skip to content

LangchainCallbackHandler and DataLayer causing issues #1928

Description

@wizhippo

Describe the bug
Using the cl.LangchainCallbackHandler and the official data layer logs have multiple reports

RuntimeError: Task <Task pending name='Task-154' coro=<ChainlitDataLayer.update_step() running at /home/wizhi/src/joy-chat/.venv/lib/python3.12/site-packages/chainlit/data/utils.py:25>> got Future <Future pending cb=[_chain_future.._call_check_cancel() at /usr/lib/python3.12/asyncio/futures.py:387]> attached to a different loop

To Reproduce
Steps to reproduce the behavior:

Run simple app: with datalayer enabled:

from dotenv import load_dotenv

load_dotenv()

import logging

logging.basicConfig(level=logging.INFO)

from typing import Dict, Optional
from langchain.chat_models import init_chat_model
from langchain_core.messages import AIMessageChunk
from langchain_core.messages import HumanMessage
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.runnables.config import RunnableConfig
from langchain_core.tools import tool
from langgraph.checkpoint.memory import MemorySaver
from langgraph.graph import StateGraph, MessagesState, START, END
from langgraph.prebuilt import ToolNode, tools_condition

import chainlit as cl


@tool
def multiply(a: int, b: int) -> int:
    """Multiply two numbers."""
    return a * b


tools = [multiply]
model = init_chat_model("openai:gpt-4o-mini", temperature=0)
model = model.bind_tools(tools)

system_prompt = """
Role:
    You are a specialized assistant.

Response Process:

1. Initial Search for Relevant Content:
    Tool: multiply
    Action: Use this tool multiply numbers
    Integration: If you find usable and pertinent information, incorporate it into your response.
    """

prompt_template = ChatPromptTemplate([
    ("system", system_prompt),
    MessagesPlaceholder("messages")
])


def should_continue(state: MessagesState):
    messages = state["messages"]
    last_message = messages[-1]
    if last_message.tool_calls:
        return "tools"
    return END


def call_model(state: MessagesState):
    messages = state['messages']
    messages = prompt_template.invoke({"messages": messages})
    response = model.invoke(messages)
    return {"messages": [response]}


workflow = StateGraph(state_schema=MessagesState)
tool_node = ToolNode(tools)

workflow.add_node("agent", call_model)
workflow.add_node("tools", tool_node)

workflow.add_edge(START, "agent")
workflow.add_conditional_edges("agent", tools_condition)
workflow.add_edge("tools", "agent")

memory = MemorySaver()

app = workflow.compile(checkpointer=memory)


@cl.password_auth_callback
def auth_callback(username: str, password: str):
    # Fetch the user matching username from your database
    # and compare the hashed password with the value stored in the database
    if (username, password) == ("admin", "admin"):
        return cl.User(
            identifier="admin", metadata={"role": "admin", "provider": "credentials"}
        )
    else:
        return None


@cl.on_message
async def main(message: cl.Message):
    answer = cl.Message(content="")
    await answer.send()

    config: RunnableConfig = {
        "callbacks": [
            cl.LangchainCallbackHandler()
        ],
        "configurable": {"thread_id": cl.context.session.thread_id}
    }

    for msg, _ in app.stream(
            {"messages": [HumanMessage(content=message.content)]},
            config,
            stream_mode="messages",
    ):
        if isinstance(msg, AIMessageChunk):
            answer.content += msg.content  # type: ignore
            await answer.update()


if __name__ == "__main__":
    from chainlit.cli import run_chainlit

    run_chainlit(__file__)

Expected behavior
Expect no errors regarding the datastore

  • OS: Ubunti 24.04
  • Browser chrome

Additional context
Errors are not present if not using the LangchainCallbackHandler

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions