File size: 11,577 Bytes
fb86b93
 
 
 
 
 
 
 
 
 
 
 
 
 
fded6e8
f484ffe
fded6e8
fb86b93
8a89e38
 
 
fb86b93
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81f75af
fb86b93
 
 
 
81f75af
fb86b93
 
 
 
81f75af
fb86b93
 
 
 
 
 
 
 
 
 
 
f484ffe
 
 
 
 
fb86b93
f484ffe
fb86b93
e58c122
fb86b93
 
 
d9e40cd
 
 
fb86b93
 
 
 
 
e58c122
f484ffe
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25eeaae
fb86b93
 
 
 
 
f484ffe
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25eeaae
d9e40cd
 
fded6e8
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
import streamlit as st
from dotenv import load_dotenv
from PyPDF2 import PdfReader
from langchain.text_splitter import CharacterTextSplitter
from langchain_community.embeddings import OpenAIEmbeddings
from langchain_community.vectorstores import FAISS
from langchain_community.chat_models import ChatOpenAI
from langchain.llms import HuggingFaceHub
from langchain import hub
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
from langchain_community.document_loaders import WebBaseLoader
import os

from session import set_rag
from partie_prenante_carte import complete_and_verify_url

def get_docs_from_website(urls):
    loader = WebBaseLoader(urls, header_template={
      'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36',
    })
    docs = loader.load()
    return docs

def get_pdf_text(pdf_docs):
    text = ""
    for pdf in pdf_docs:
        pdf_reader = PdfReader(pdf)
        for page in pdf_reader.pages:
            text += page.extract_text()
    return text

def get_text_chunks(text):
    text_splitter = CharacterTextSplitter(
        separator="\n",
        chunk_size=1000, # the character length of the chunck
        chunk_overlap=200, # the character length of the overlap between chuncks
        length_function=len # the length function - in this case, character length (aka the python len() fn.)
    )
    chunks = text_splitter.split_text(text)
    return chunks

def get_doc_chunks(docs):
    # Split the loaded data
    text_splitter = CharacterTextSplitter(separator='\n', 
                                chunk_size=500, 
                                chunk_overlap=40)

    docs = text_splitter.split_documents(docs)
    return docs

def get_vectorstore_from_docs(doc_chunks):
    embedding = OpenAIEmbeddings(model="text-embedding-3-small")
    vectorstore = FAISS.from_documents(documents=doc_chunks, embedding=embedding)
    return vectorstore

def get_vectorstore(text_chunks):
    embedding = OpenAIEmbeddings(model="text-embedding-3-small")
    vectorstore = FAISS.from_texts(texts=text_chunks, embedding=embedding)
    return vectorstore

def get_conversation_chain(vectorstore):
    llm = ChatOpenAI(model="gpt-3.5-turbo",temperature=0.5, max_tokens=2048)
    retriever=vectorstore.as_retriever()
    prompt = hub.pull("rlm/rag-prompt")
    
    # Chain
    rag_chain = (
        {"context": retriever , "question": RunnablePassthrough()}
        | prompt
        | llm
    )
    return rag_chain

def verify_and_complete_urls(urls):
    for i in range(len(urls)):
        is_valid, urls[i] = complete_and_verify_url(urls[i])
    return urls

def rag_pdf_web():

    load_dotenv()
    st.header("INDIQUEZ VOS PAGES WEB ET/OU DOCUMENTS D’ENTREPRISE POUR AUDITER LE CONTENU RSE")
    
    option = st.radio("Source", ("A partir de votre site web", "A partir de vos documents entreprise"))

    vectorstore = None
    chain = None
    
    if option == "A partir de votre site web":
        url1 = st.text_input("URL 1")
        url2 = st.text_input("URL 2")
        url3 = st.text_input("URL 3")
        # Process the URLs
        sous_options = st.radio("Choisissez votre sous-section", ("Ambition, Vision, Missions, Valeurs", "3 piliers de la démarche RSE"))
        try:
            if st.button("Process"):
                with st.spinner("Processing..."):
                    #get text from the website
                    urls = [url1, url2, url3]
                    filtered_urls = [url for url in urls if url]
                    
                    #verify and complete urls
                    filtered_urls = verify_and_complete_urls(filtered_urls)

                    #get text from the website
                    docs = get_docs_from_website(filtered_urls)

                    #get text chunks
                    text_chunks = get_doc_chunks(docs)

                    #create vectorstore
                    vectorstore = get_vectorstore_from_docs(text_chunks)

                    chain = get_conversation_chain(vectorstore)

                    if sous_options == "Ambition, Vision, Missions, Valeurs":
                        # question = '''voici les 4 points à génerer absolument, pas de reponse comme je ne sais pas; et n'oublie aucun des points , chaque paragraphe doit être de minimum 150 caractères:
                        #                 \n
                        #                 ### Ambition : \n
                        #                 Quelle est l'ambition de l'entreprise ? (répondre avec maximum 250 caractères)
                        #                 \n
                        #                 ### Vision : \n
                        #                 Quelle est la vision de l'entreprise ? (répondre avec maximum 250 caractères)
                        #                 \n
                        #                 ### Missions : \n
                        #                 Quelles sont les missions de l'entreprise ? (répondre avec maximum 250 caractères)
                        #                 \n
                        #                 renvoie ta réponse en markdown et bien formatée'''
                        # response = chain.invoke(question)
                        # st.markdown(response.content)

                        #ambition
                        ambition = chain.invoke("Quelle est l'ambition de l'entreprise ? (répondre avec maximum 250 caractères)")
                        st.markdown("### Ambition :")
                        st.markdown(ambition.content)

                        #vision
                        ambition = chain.invoke(" Quelle est la vision de l'entreprise ? (répondre avec maximum 250 caractères)")
                        st.markdown("### Vision :")
                        st.markdown(ambition.content)

                        #Mission
                        ambition = chain.invoke(" Quelle est la vision de l'entreprise ? (répondre avec maximum 250 caractères)")
                        st.markdown("### Mission :")
                        st.markdown(ambition.content)

                        #values
                        values = chain.invoke("Quels sont les valeurs de l'entreprise ? (répondre avec 10 mots maximum en bullet points)")
                        st.markdown("### Valeurs :")
                        st.markdown(values.content)
                    
                    elif sous_options == "3 piliers de la démarche RSE":
                        question = '''  suggère nous les 3 piliers principaux de la démarche RSE pour cette entreprise. N'oublie aucun pilier RSE , ca doit avoir ce format :
                                        \n
                                        ### le titre du  pilier numero 1 \n
                                        -la description du pilier (répondre avec maximum 250 caractères)
                                        \n
                                        - 2 indicateurs cibles pertinents à atteindre avec suggestion de valeur cible min, max
                                        \n
                                        ### le titre du  pilier numero 2 \n
                                        -la description du pilier (répondre avec maximum 250 caractères)
                                        \n
                                        - 2 indicateurs cibles pertinents à atteindre avec suggestion de valeur cible min, max
                                        \n
                                        ### le titre du  pilier numero 3 \n
                                        -la description du pilier (répondre avec maximum 250 caractères)
                                        \n
                                        - 2 indicateurs cibles pertinents à atteindre avec suggestion de valeur cible min, max
                                        \n
                                        renvoie ta réponse en markdown et bien formatée
                                        '''
                        response = chain.invoke(question)
                        st.markdown(response.content)
        except Exception as e:
            st.error(f"Une erreur s'est produite : Url non valide ou problème de connexion à internet. Veuillez réessayer.")

    if option == "A partir de vos documents entreprise":
        pdf_docs = st.file_uploader("Upload les documents concernant la marque (maximum 3 fichiers de taille max de 5 Mo)", type="pdf", accept_multiple_files=True)
        # Process the PDF documents
        sous_options = st.radio("Choisissez votre sous-section", ("Ambition, Vision, Missions, Valeurs", "3 piliers de la démarche RSE"))
        try:
            if st.button("Process"):
                with st.spinner("Processing..."):
                    #get pdf text in raw format
                    raw_text = get_pdf_text(pdf_docs)

                    #get text chunks
                    text_chunks = get_text_chunks(raw_text)

                    #create vectorstore
                    vectorstore = get_vectorstore(text_chunks)

                    chain = get_conversation_chain(vectorstore)

                    if sous_options == "Ambition, Vision, Missions, Valeurs":

                        #ambition
                        ambition = chain.invoke("Quelle est l'ambition de l'entreprise ? (répondre avec maximum 250 caractères)")
                        st.markdown("### Ambition :")
                        st.markdown(ambition.content)

                        #vision
                        ambition = chain.invoke(" Quelle est la vision de l'entreprise ? (répondre avec maximum 250 caractères)")
                        st.markdown("### Vision :")
                        st.markdown(ambition.content)

                        #Mission
                        ambition = chain.invoke(" Quelle est la vision de l'entreprise ? (répondre avec maximum 250 caractères)")
                        st.markdown("### Mission :")
                        st.markdown(ambition.content)

                        #values
                        values = chain.invoke("Quels sont les valeurs de l'entreprise ? (répondre avec 10 mots maximum en bullet points)")
                        st.markdown("### Valeurs :")
                        st.markdown(values.content)
                    
                    elif sous_options == "3 piliers de la démarche RSE":
                        question = '''  suggère nous les 3 piliers principaux de la démarche RSE pour cette entreprise. Pour chaque pilier RSE doit avoir ce format :
                                        \n
                                        ### le titre du ieme pilier \n
                                        -la description du pilier (répondre avec maximum 250 caractères)
                                        \n
                                        - 2 indicateurs cibles pertinents à atteindre avec suggestion de valeur cible min, max
                                        \n
                                        renvoie ta réponse en markdown et bien formatée
                                        '''
                        response = chain.invoke(question)
                        st.markdown(response.content)
        except Exception as e:
            st.error(f"Une erreur s'est produite : Pdf non valide ou problème de connexion à internet. Veuillez réessayer.")

    if vectorstore and chain:
        set_rag(vectorstore, chain)