import os import json import bcrypt import pandas as pd import numpy as np import plotly.express as px import plotly.graph_objects as go from plotly.subplots import make_subplots import matplotlib.pyplot as plt from wordcloud import WordCloud from typing import List from pathlib import Path from langchain_openai import ChatOpenAI from langchain.schema.runnable.config import RunnableConfig from langchain.schema import StrOutputParser from langchain_core.prompts import ChatPromptTemplate from langchain.agents import AgentExecutor from langchain.agents.agent_types import AgentType from langchain_experimental.agents.agent_toolkits import create_pandas_dataframe_agent, create_csv_agent import chainlit as cl from chainlit.input_widget import TextInput, Select, Switch, Slider from deep_translator import GoogleTranslator from IPython.display import display from surveycaa import surveyCaa @cl.password_auth_callback def auth_callback(username: str, password: str): auth = json.loads(os.environ['CHAINLIT_AUTH_LOGIN']) ident = next(d['ident'] for d in auth if d['ident'] == username) pwd = next(d['pwd'] for d in auth if d['ident'] == username) resultLogAdmin = bcrypt.checkpw(username.encode('utf-8'), bcrypt.hashpw(ident.encode('utf-8'), bcrypt.gensalt())) resultPwdAdmin = bcrypt.checkpw(password.encode('utf-8'), bcrypt.hashpw(pwd.encode('utf-8'), bcrypt.gensalt())) resultRole = next(d['role'] for d in auth if d['ident'] == username) if resultLogAdmin and resultPwdAdmin and resultRole == "admindatapcc": return cl.User( identifier=ident + " : đŸ§‘â€đŸ’Œ Admin Datapcc", metadata={"role": "admin", "provider": "credentials"} ) elif resultLogAdmin and resultPwdAdmin and resultRole == "userdatapcc": return cl.User( identifier=ident + " : 🧑‍🎓 User Datapcc", metadata={"role": "user", "provider": "credentials"} ) def create_agent(filename: str): """ Create an agent that can access and use a large language model (LLM). Args: filename: The path to the CSV file that contains the data. Returns: An agent that can access and use the LLM. """ # Create an OpenAI object. os.environ['OPENAI_API_KEY'] = os.environ['OPENAI_API_KEY'] llm = ChatOpenAI(temperature=0, model="gpt-4o-2024-05-13") # Read the CSV file into a Pandas DataFrame. df = pd.read_csv(filename) # Create a Pandas DataFrame agent. return create_csv_agent(llm, filename, verbose=False, allow_dangerous_code=True, handle_parsing_errors=True, agent_type=AgentType.OPENAI_FUNCTIONS) def query_agent(agent, query): """ Query an agent and return the response as a string. Args: agent: The agent to query. query: The query to ask the agent. Returns: The response from the agent as a string. """ prompt = ( """ For the following query, if it requires drawing a table, reply as follows: {"table": {"columns": ["column1", "column2", ...], "data": [[value1, value2, ...], [value1, value2, ...], ...]}} If the query requires creating a bar chart, reply as follows: {"bar": {"columns": ["A", "B", "C", ...], "data": [25, 24, 10, ...]}} If the query requires creating a line chart, reply as follows: {"line": {"columns": ["A", "B", "C", ...], "data": [25, 24, 10, ...]}} There can only be two types of chart, "bar" and "line". If it is just asking a question that requires neither, reply as follows: {"answer": "answer"} Example: {"answer": "The title with the highest rating is 'Gilead'"} If you do not know the answer, reply as follows: {"answer": "I do not know."} Return all output as a string. All strings in "columns" list and data list, should be in double quotes, For example: {"columns": ["title", "ratings_count"], "data": [["Gilead", 361], ["Spider's Web", 5164]]} Lets think step by step. Below is the query. Query: """ + query ) # Run the prompt through the agent. response = agent.invoke(prompt) # Convert the response to a string. return response.__str__() def decode_response(response: str) -> dict: """This function converts the string response from the model to a dictionary object. Args: response (str): response from the model Returns: dict: dictionary with response data """ return json.loads("[" + response + "]") def write_response(response_dict: dict): """ Write a response from an agent to a Streamlit app. Args: response_dict: The response from the agent. Returns: None. """ # Check if the response is an answer. return response_dict["answer"] @cl.action_callback("Download") async def on_action(action): content = [] content.append(action.value) arrayContent = np.array(content) df = pd.DataFrame(arrayContent) with open('./' + action.description + '.txt', 'wb') as csv_file: df.to_csv(path_or_buf=csv_file, index=False,header=False, encoding='utf-8') elements = [ cl.File( name= action.description + ".txt", path="./" + action.description + ".txt", display="inline", ), ] await cl.Message( content="[Lien] 🔗", elements=elements ).send() await action.remove() @cl.set_chat_profiles async def chat_profile(): return [ cl.ChatProfile(name="Traitement des donnĂ©es d'enquĂȘte : «ExpĂ© CFA : questionnaire auprĂšs des professionnels de la branche de l'agencement»",markdown_description="VidĂ©o exploratoire autour de l'Ă©vĂ©nement",icon="/public/logo-ofipe.png",), ] #@cl.set_starters #async def set_starters(): # return [ # cl.Starter( # label="RĂ©partition du nombre de CAA dans les entreprises", # message="Quel est le nombre de chargĂ©.e d'affaires en agencement dans chaque type d'entreprises?", # icon="/public/request-theme.svg", # ) # ] @cl.on_chat_start async def on_chat_start(): await cl.Message(f"> SURVEYIA").send() surveyCaa() @cl.on_message async def on_message(message: cl.Message): await cl.Message(f"> SURVEYIA").send() agent = create_agent("./public/surveyia.csv") cb = cl.AsyncLangchainCallbackHandler() try: res = await agent.acall("RĂ©ponds en langue française Ă  la question suivante : " + message.content, callbacks=[cb]) await cl.Message(author="COPILOT",content=GoogleTranslator(source='auto', target='fr').translate(res['output'])).send() except ValueError as e: res = str(e) resArray = res.split(":") ans = '' if str(res).find('parsing') != -1: for i in range(2,len(resArray)): ans += resArray[i] await cl.Message(author="COPILOT",content=ans.replace("`","")).send() else: await cl.Message(author="COPILOT",content="Reformulez votre requĂȘte, s'il vous plait 😃").send() # Query the agent. #response = query_agent(agent=agent, query=message.content) # Decode the response. #decoded_response = decode_response(response) # Write the response to the Streamlit app. #result = write_response(decoded_response) #await cl.Message(author="COPILOT",content=GoogleTranslator(source='auto', target='fr').translate(result)).send()