code: import logging
  
  import chainlit as cl
  import lancedb
  import pandas as pd
  from langchain import LLMChain
  from langchain.agents.agent_toolkits import create_conversational_retrieval_agent
  from langchain.agents.agent_toolkits import create_retriever_tool
  from langchain.chat_models import ChatOpenAI
  from langchain.embeddings import OpenAIEmbeddings
  from langchain.schema import SystemMessage
  from langchain.vectorstores import LanceDB
  
  OPENAI_MODEL = "gpt-3.5-turbo-16k"  # "gpt-3.5-turbo"
  
  logger = logging.getLogger(__name__)
  
  recipes = pd.read_pickle("data/preprocessed/recipes.pkl")
  recipes.drop_duplicates(subset=["id"], inplace=True)  # Must for this dataset
  recipes.drop("target", axis=1, inplace=True)
  
  uri = "dataset/chainlit-recipes-lancedb"
  db = lancedb.connect(uri)
  table = db.create_table("recipes", recipes, mode="overwrite")
  
  
  @cl.on_chat_start
  async def main():
      embeddings = OpenAIEmbeddings()
      docsearch = await cl.make_async(LanceDB)(connection=table, embedding=embeddings)
      llm = ChatOpenAI(model=OPENAI_MODEL, temperature=0)
  
      tool = create_retriever_tool(
          docsearch.as_retriever(search_kwargs={"k": 10}),  # kan kalle denne dynamisk for menyer
          "recommend_recipes_or_menus",
          "Recommends dinner recipes or menus based on user preferences. Invocations must be in norwegian.",
      )
      tools = [tool]
      system_message = SystemMessage(
          content=(
              """You are a recommender chatting with the user to provide dinner recipe recommendation. You must follow the instructions below during chat. You can recommend either a recipe plan for a week or single recipes. 
                  If you do not have enough information about user preference, you should ask the user for his preference.
                  If you have enough information about user preference, you can give recommendation. The recommendation list can contain items that the dialog mentioned before.
                  Recommendations are given by using the tool recommend_recipes_or_menus with a query you think matches the conversation and user preferences. The query must be in norwegian."""
          )
      )
  
      qa = create_conversational_retrieval_agent(
          llm,
          tools,
          system_message=system_message,
          remember_intermediate_steps=True,
          # max_tokens_limit=4000,
          verbose=True,
      )
  
      # Store the chain in the user session
      cl.user_session.set("llm_chain", qa)
  
  
  @cl.on_message
  async def main(message: cl.Message):
      print(message)
      # Retrieve the chain from the user session
      llm_chain = cl.user_session.get("llm_chain")  # type: LLMChain
  
      # Call the chain asynchronously
      res = await llm_chain.acall(message.content, callbacks=[cl.AsyncLangchainCallbackHandler()])
  
      # Do any post-processing here
      await cl.Message(content=res["output"]).send()
  
  # HOW TO RUN: chainlit run app.py -w
  
apis: lancedb.connect
extract_api: [((498, 525), 'logging.getLogger', 'logging.getLogger', (['__name__'], {}), '(__name__)\n', (515, 525), False, 'import logging\n'), ((537, 584), 'pandas.read_pickle', 'pd.read_pickle', (['"""data/preprocessed/recipes.pkl"""'], {}), "('data/preprocessed/recipes.pkl')\n", (551, 584), True, 'import pandas as pd\n'), ((755, 775), 'lancedb.connect', 'lancedb.connect', (['uri'], {}), '(uri)\n', (770, 775), False, 'import lancedb\n'), ((893, 911), 'langchain.embeddings.OpenAIEmbeddings', 'OpenAIEmbeddings', ([], {}), '()\n', (909, 911), False, 'from langchain.embeddings import OpenAIEmbeddings\n'), ((1007, 1052), 'langchain.chat_models.ChatOpenAI', 'ChatOpenAI', ([], {'model': 'OPENAI_MODEL', 'temperature': '(0)'}), '(model=OPENAI_MODEL, temperature=0)\n', (1017, 1052), False, 'from langchain.chat_models import ChatOpenAI\n'), ((1375, 2106), 'langchain.schema.SystemMessage', 'SystemMessage', ([], {'content': '"""You are a recommender chatting with the user to provide dinner recipe recommendation. You must follow the instructions below during chat. You can recommend either a recipe plan for a week or single recipes. \n                If you do not have enough information about user preference, you should ask the user for his preference.\n                If you have enough information about user preference, you can give recommendation. The recommendation list can contain items that the dialog mentioned before.\n                Recommendations are given by using the tool recommend_recipes_or_menus with a query you think matches the conversation and user preferences. The query must be in norwegian."""'}), '(content=\n    """You are a recommender chatting with the user to provide dinner recipe recommendation. You must follow the instructions below during chat. You can recommend either a recipe plan for a week or single recipes. \n                If you do not have enough information about user preference, you should ask the user for his preference.\n                If you have enough information about user preference, you can give recommendation. The recommendation list can contain items that the dialog mentioned before.\n                Recommendations are given by using the tool recommend_recipes_or_menus with a query you think matches the conversation and user preferences. The query must be in norwegian."""\n    )\n', (1388, 2106), False, 'from langchain.schema import SystemMessage\n'), ((2145, 2278), 'langchain.agents.agent_toolkits.create_conversational_retrieval_agent', 'create_conversational_retrieval_agent', (['llm', 'tools'], {'system_message': 'system_message', 'remember_intermediate_steps': '(True)', 'verbose': '(True)'}), '(llm, tools, system_message=\n    system_message, remember_intermediate_steps=True, verbose=True)\n', (2182, 2278), False, 'from langchain.agents.agent_toolkits import create_conversational_retrieval_agent\n'), ((2401, 2437), 'chainlit.user_session.set', 'cl.user_session.set', (['"""llm_chain"""', 'qa'], {}), "('llm_chain', qa)\n", (2420, 2437), True, 'import chainlit as cl\n'), ((2574, 2606), 'chainlit.user_session.get', 'cl.user_session.get', (['"""llm_chain"""'], {}), "('llm_chain')\n", (2593, 2606), True, 'import chainlit as cl\n'), ((934, 956), 'chainlit.make_async', 'cl.make_async', (['LanceDB'], {}), '(LanceDB)\n', (947, 956), True, 'import chainlit as cl\n'), ((2804, 2837), 'chainlit.Message', 'cl.Message', ([], {'content': "res['output']"}), "(content=res['output'])\n", (2814, 2837), True, 'import chainlit as cl\n'), ((2722, 2756), 'chainlit.AsyncLangchainCallbackHandler', 'cl.AsyncLangchainCallbackHandler', ([], {}), '()\n', (2754, 2756), True, 'import chainlit as cl\n')]