File size: 7,004 Bytes
bcaf45a
 
b29a90e
 
 
 
 
 
 
 
 
 
 
1a14ce1
b29a90e
 
 
4d0f4a6
 
b29a90e
 
 
 
 
 
bcaf45a
b29a90e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bcaf45a
 
 
 
ffe2e34
bcaf45a
b29a90e
bcaf45a
b29a90e
 
 
67c87e7
1a14ce1
5ac7d7a
b29a90e
 
 
 
 
 
 
5ac7d7a
4d0f4a6
 
 
b29a90e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
from langchain_community.llms import HuggingFaceEndpoint
from langchain_core.prompts import PromptTemplate
from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain.memory import ChatMessageHistory, ConversationBufferMemory
from langchain.schema import StrOutputParser
from langchain.schema.runnable import Runnable, RunnablePassthrough, RunnableLambda
from langchain.schema.runnable.config import RunnableConfig
from langchain.schema import StrOutputParser
from langchain.document_loaders.csv_loader import CSVLoader
import os
import pandas as pd
import numpy as np

from langchain.agents import AgentExecutor
from langchain.agents.agent_types import AgentType
from langchain_experimental.agents.agent_toolkits import create_csv_agent

from deep_translator import GoogleTranslator

import chainlit as cl

def library():
    return "Exemple de requêtes sur les données des emplois'.\n\nQ1 : donne les 10 métiers principaux. Génère le résultat dans un tableau avec les compétences représentatives correspondant à chaque emploi.\nQ2 : donne les 10 compétences principales. Génère le résultat dans un tableau avec les emplois représentatifs correspondant à chaque compétence.\nQ3 : donne les 10 compétences principales. Génère le résultat dans un tableau avec les niveaux de qualification représentatifs correspondant à chaque compétence.\nQ4 : donne les 10 compétences principales. Génère le résultat dans un tableau avec les salaires représentatifs correspondant à chaque compétence.\nQ5 : donne les 10 compétences principales. Génère le résultat dans un tableau avec les contrats représentatifs correspondant à chaque compétence.\nQ6 : donne les 10 contrats principaux. Génère le résultat dans un tableau avec les emplois représentatifs correspondant à chaque contrat."
@cl.author_rename
def rename(orig_author: str):
    rename_dict = {"AgentExecutor": "Agent conversationnel", "Error": "Réponse de l'assistant", "DatapccSkillStream": "Copilot", "load_memory_variables": "Historique de conversation 💬", "Retriever": "Agent conversationnel", "StuffDocumentsChain": "Chaîne de documents", "LLMChain": "Agent", "HuggingFaceEndpoint": "Réponse de Mistral AI 🤖"}
    return rename_dict.get(orig_author, orig_author)

@cl.on_chat_start
async def on_chat_start():
    await cl.Message(f"> Votre assistant conversationnel vous permet d'analyser les données du marché de l'emploi par formation, issues de France Travail.").send()
    listPrompts_name = f"Liste des requêtes"
    prompt_elements = []
    prompt_elements.append(
        cl.Text(content=library(), name=listPrompts_name)
    )
    await cl.Message(content="📚 Bibliothèque de questions : " + listPrompts_name, elements=prompt_elements).send()
    await cl.Avatar(
        name="You",
        url="https://cipen.univ-gustave-eiffel.fr/typo3conf/ext/cipen_package/Resources/Public/Dataviz/datalab/Venus/logo-ofipe.jpg",
    ).send()
    
    loader = CSVLoader(file_path="./public/FilesMarcheEmploi.csv", csv_args={"delimiter": ",", "fieldnames": ["Label", "Number"],},)

    data = loader.load()
    actions = []
    for j in range(0,len(data)):
        datas = data[j].page_content
        datasArray = datas.split(':')
        label = datasArray[1].replace('Number','')
        value = datasArray[2]
        actions.append(cl.Action(name="selectRome", value=value, label=label),)

    selectRome = await cl.AskActionMessage(
        content="Sélectionnez une formation pour laquelle le COPILOT vous assistera :",
        actions=actions,
        timeout=600,
    ).send()

    if selectRome and selectRome.get("name") == "selectRome":
        await cl.Message(
            content=f"Vous pouvez utiliser le COPILOT pour répondre à vos questions sur : \"{selectRome.get('label')}\", Codes ROME : \"{selectRome.get('value')}\"",
        ).send()
        selectRomes = selectRome.get('value')
        os.environ['HUGGINGFACEHUB_API_TOKEN'] = os.environ['HUGGINGFACEHUB_API_TOKEN']
        repo_id = "mistralai/Mixtral-8x7B-Instruct-v0.1"

        llm = HuggingFaceEndpoint(
            repo_id=repo_id, temperature=1.0
        )
        agent = create_csv_agent(
            llm,
            "https://cipen.univ-gustave-eiffel.fr/typo3conf/ext/cipen_package/Resources/Public/Dataviz/datalab/crossfilterings/EmploisRome/" + selectRomes[1:] + ".csv",
            verbose=False,
            agent_type=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
            max_iterations=3,
        )
        cl.user_session.set("runnable", agent)

@cl.on_message
async def on_message(message: cl.Message):
    memory= cl.user_session.get("memory")
    runnable = cl.user_session.get("runnable")  # type: Runnable
    cb = cl.AsyncLangchainCallbackHandler()
    try:
        res = await runnable.acall("Tu es un spécialiste du marché de l'emploi. Tu es en capacité d'analyser les emplois et d'en décrire les caractéristiques par rapport aux types de contrat, par rapport aux compétences professionnelles, par rapport aux niveaux de qualification. Réponds en langue française à la question suivante : " + message.content + "\nSi l'information est manquante ou de type nan, fais un projection ou une estimation.\nDétaille la réponse en faisant une analyse complète sachant que la colonne Poste correspond à la colonne des emplois, la colonne Contrat correspond à la colonne des types de contrat, la colonne Savoir correspond à la colonne des compétences professionnelles demandées par les employeurs, la colonne Localisation correspond à la colonne des départements, la colonne Niveau correspond à la colonne des niveaux de qualification.", callbacks=[cb])
        translated = GoogleTranslator(source='auto', target='de').translate("keep it up, you are awesome")
        
        await cl.Message(author="COPILOT",content=GoogleTranslator(source='auto', target='fr').translate(res['output'])).send()
        listPrompts_name = f"Liste des requêtes"
        prompt_elements = []
        prompt_elements.append(
            cl.Text(content=library(), name=listPrompts_name)
        )
        await cl.Message(content="📚 Bibliothèque de questions : " + listPrompts_name, elements=prompt_elements).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()
            listPrompts_name = f"Liste des requêtes"
            prompt_elements = []
            prompt_elements.append(
                cl.Text(content=library(), name=listPrompts_name)
            )
            await cl.Message(content="📚 Bibliothèque de questions : " + listPrompts_name, elements=prompt_elements).send()
        else:
            await cl.Message(author="COPILOT",content="Reformulez votre requête, s'il vous plait 😃").send()