Ilyas KHIAT commited on
Commit
c2f2340
·
1 Parent(s): 9b707db
app.py CHANGED
@@ -11,13 +11,14 @@ def main():
11
  audit_page = st.Page("audit_page/audit.py", title="Audit", icon="📋", default=True)
12
  kg_page = st.Page("audit_page/knowledge_graph.py", title="Graphe de connaissance", icon="🧠")
13
  agents_page = st.Page("agents_page/catalogue.py", title="Catalogue des agents", icon="📇")
 
14
  recommended_agents = st.Page("agents_page/recommended_agent.py", title="Agents recommandés", icon="⭐")
15
  chatbot = st.Page("chatbot_page/chatbot.py", title="Chatbot", icon="💬")
16
  documentation = st.Page("doc_page/documentation.py", title="Documentation", icon="📚")
17
 
18
  pg = st.navigation(
19
  {
20
- "Audit de contenus": [audit_page, kg_page],
21
  "Equipe d'agents IA": [recommended_agents],
22
  "Chatbot": [chatbot],
23
  "Documentation": [documentation]
 
11
  audit_page = st.Page("audit_page/audit.py", title="Audit", icon="📋", default=True)
12
  kg_page = st.Page("audit_page/knowledge_graph.py", title="Graphe de connaissance", icon="🧠")
13
  agents_page = st.Page("agents_page/catalogue.py", title="Catalogue des agents", icon="📇")
14
+ compte_rendu = st.Page("audit_page/compte_rendu.py", title="Compte rendu", icon="📝")
15
  recommended_agents = st.Page("agents_page/recommended_agent.py", title="Agents recommandés", icon="⭐")
16
  chatbot = st.Page("chatbot_page/chatbot.py", title="Chatbot", icon="💬")
17
  documentation = st.Page("doc_page/documentation.py", title="Documentation", icon="📚")
18
 
19
  pg = st.navigation(
20
  {
21
+ "Audit de contenus": [audit_page, compte_rendu, kg_page],
22
  "Equipe d'agents IA": [recommended_agents],
23
  "Chatbot": [chatbot],
24
  "Documentation": [documentation]
audit_page/compte_rendu.py ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from textwrap import dedent
3
+ from utils.audit.rag import get_text_from_content_for_doc,get_text_from_content_for_audio
4
+ from utils.audit.response_llm import generate_response_via_langchain
5
+ from langchain_core.messages import AIMessage, HumanMessage
6
+ import pyperclip
7
+
8
+
9
+ def cr_main():
10
+ st.title("Compte rendu")
11
+
12
+ if "audit" not in st.session_state or st.session_state.audit == {}:
13
+ st.error("Veuillez d'abord effectuer un audit pour générer un compte rendu.")
14
+ return
15
+
16
+ if "cr" not in st.session_state:
17
+ st.session_state.cr = ""
18
+
19
+ if "cr_chat_history" not in st.session_state:
20
+ st.session_state.cr_chat_history = [
21
+ ]
22
+
23
+ audit = st.session_state.audit_simplified
24
+ content = st.session_state.audit["content"]
25
+
26
+ if audit["type de fichier"] == "pdf":
27
+ text = get_text_from_content_for_doc(content)
28
+ elif audit["type de fichier"] == "audio":
29
+ text = get_text_from_content_for_audio(content)
30
+
31
+ prompt_cr = dedent(f'''
32
+
33
+ À partir du document ci-dessous, générez un compte rendu détaillé contenant les sections suivantes :
34
+
35
+ 2. **Résumé** : Fournissez un résumé concis du document, en mettant en avant les points principaux, les relations essentielles, les concepts , les dates et les lieux, les conclusions et les détails importants.
36
+
37
+ 3. **Notes** :
38
+ - Présentez les points clés sous forme de liste à puces avec des émojis pertinents pour souligner la nature de chaque point.
39
+ - Incluez des sous-points (sans émojis) sous les points principaux pour offrir des détails ou explications supplémentaires.
40
+
41
+ 4. **Actions** : Identifiez et listez les actions spécifiques, tâches ou étapes recommandées ou nécessaires selon le contenu du document.
42
+
43
+ **Document :**
44
+
45
+ {text}
46
+
47
+ **Format de sortie :**
48
+
49
+
50
+ ### Résumé :
51
+ [Fournissez un résumé concis du document ici.]
52
+
53
+ ### Notes :
54
+ - 📌 **Point Principal 1**
55
+ - Sous-point A
56
+ - Sous-point B
57
+ - 📈 **Point Principal 2**
58
+ - Sous-point C
59
+ - Sous-point D
60
+ - 📝 **Point Principal 3**
61
+ - Sous-point E
62
+ - Sous-point F
63
+
64
+ ### Actions :
65
+ 1. [Action 1]
66
+ 2. [Action 2]
67
+ 3. [Action 3]
68
+ 4. ...
69
+
70
+ ---
71
+ ''')
72
+
73
+
74
+
75
+ if st.button("Générer compte rendu"):
76
+
77
+ with st.spinner("Génération du compte rendu..."):
78
+ cr = generate_response_via_langchain(prompt_cr,stream=False,model="gpt-4o")
79
+ st.session_state.cr = cr
80
+ st.session_state.cr_chat_history = []
81
+
82
+ else:
83
+ cr = st.session_state.cr
84
+
85
+ if cr:
86
+ col1, col2 = st.columns([2.5, 1.5])
87
+
88
+ with col1.container(border=True,height=800):
89
+ st.markdown("##### Compte rendu")
90
+ st.markdown("### Mots clés extraits:")
91
+ st.write(f"- {audit['Mots clés'].strip()}")
92
+ st.write(cr)
93
+ if st.button("📋",key="copy_transcription"):
94
+ pyperclip.copy(content["transcription"])
95
+ st.success("Transcription copiée dans le presse-papier")
96
+
97
+ with col2.container(border=True,height=800):
98
+ st.markdown("##### Dialoguer avec le CR")
99
+
100
+ user_query = st.chat_input("Par ici ...")
101
+ if user_query is not None and user_query != "":
102
+ st.session_state.cr_chat_history.append(HumanMessage(content=user_query))
103
+
104
+ with st.container(height=650, border=False):
105
+ for message in st.session_state.cr_chat_history:
106
+ if isinstance(message, AIMessage):
107
+ with st.chat_message("AI"):
108
+ st.markdown(message.content)
109
+ elif isinstance(message, HumanMessage):
110
+ with st.chat_message("Moi"):
111
+ st.write(message.content)
112
+
113
+ #check if last message is human message
114
+ if len(st.session_state.cr_chat_history) > 0:
115
+ last_message = st.session_state.cr_chat_history[-1]
116
+ if isinstance(last_message, HumanMessage):
117
+ with st.chat_message("AI"):
118
+ retreive = st.session_state.vectorstore.as_retriever()
119
+ context = retreive.invoke(last_message.content)
120
+ wrapped_prompt = f'''Étant donné le contexte suivant {context} et le compte rendu du document {cr}, {last_message.content}'''
121
+ response = st.write_stream(generate_response_via_langchain(wrapped_prompt,stream=True))
122
+ st.session_state.cr_chat_history.append(AIMessage(content=response))
123
+
124
+
125
+ cr_main()
126
+
127
+
128
+
129
+
audit_page/knowledge_graph.py CHANGED
@@ -6,6 +6,7 @@ import random
6
  import math
7
  from utils.audit.response_llm import generate_response_via_langchain
8
  from langchain_core.messages import AIMessage, HumanMessage
 
9
 
10
  def if_node_exists(nodes, node_id):
11
  """
@@ -150,8 +151,13 @@ def kg_main():
150
  st.error("Veuillez d'abord effectuer un audit pour visualiser le graphe de connaissance.")
151
  return
152
 
 
 
 
 
153
  if "graph" not in st.session_state:
154
  st.session_state.graph = None
 
155
  st.title("Graphe de connaissance")
156
 
157
  if "node_types" not in st.session_state:
@@ -164,12 +170,14 @@ def kg_main():
164
  st.session_state.chat_graph_history = []
165
 
166
  audit = st.session_state.audit_simplified
167
- content = st.session_state.audit["content"]
168
 
169
- if audit["type de fichier"] == "pdf":
170
- text = get_text_from_content_for_doc(content)
171
- elif audit["type de fichier"] == "audio":
172
- text = get_text_from_content_for_audio(content)
 
 
173
 
174
  #summary_prompt = f"Voici un ensemble de documents : {text}. À partir de ces documents, veuillez fournir des résumés concis en vous concentrant sur l'extraction des relations essentielles et des événements. Il est crucial d'inclure les dates des actions ou des événements, car elles seront utilisées pour l'analyse chronologique. Par exemple : 'Sam a été licencié par le conseil d'administration d'OpenAI le 17 novembre 2023 (17 novembre, vendredi)', ce qui illustre la relation entre Sam et OpenAI ainsi que la date de l'événement."
175
 
@@ -179,7 +187,9 @@ def kg_main():
179
  # st.session_state.summary = sum
180
 
181
  with st.spinner("Génération du graphe..."):
182
- graph = get_graph(text)
 
 
183
  st.session_state.graph = graph
184
 
185
  node_types = get_node_types(graph[0])
@@ -212,34 +222,39 @@ def kg_main():
212
  with col2.container(border=True,height=800):
213
  st.markdown("##### Dialoguer avec le graphe")
214
 
215
- for message in st.session_state.chat_graph_history:
216
- if isinstance(message, AIMessage):
217
- with st.chat_message("AI"):
218
- st.markdown(message.content)
219
- elif isinstance(message, HumanMessage):
220
- with st.chat_message("Moi"):
221
- st.write(message.content)
222
-
223
- #check if last message is human message
224
- if len(st.session_state.chat_graph_history) > 0:
225
- last_message = st.session_state.chat_graph_history[-1]
226
- if isinstance(last_message, HumanMessage):
227
- with st.chat_message("AI"):
228
- retreive = st.session_state.vectorstore.as_retriever()
229
- context = retreive.invoke(last_message.content)
230
- wrapped_prompt = f"Étant donné le contexte suivant {context}, {last_message.content}"
231
- response = st.write_stream(generate_response_via_langchain(wrapped_prompt,stream=True))
232
- st.session_state.chat_graph_history.append(AIMessage(content=response))
233
-
234
- if selected is not None:
235
- with st.chat_message("AI"):
236
- st.markdown(f" EXPLORER LES DONNEES CONTENUES DANS **{selected}**")
237
-
238
- prompts = [f"Extrait moi toutes les informations du noeud ''{selected}'' ➡️",
239
- f"Montre moi les conversations autour du noeud ''{selected}'' ➡️"]
240
-
241
- for i,prompt in enumerate(prompts):
242
- button = st.button(prompt,key=f"p_{i}",on_click=lambda i=i: st.session_state.chat_graph_history.append(HumanMessage(content=prompts[i])))
 
 
 
 
 
243
 
244
 
245
 
 
6
  import math
7
  from utils.audit.response_llm import generate_response_via_langchain
8
  from langchain_core.messages import AIMessage, HumanMessage
9
+ from langchain_core.prompts import PromptTemplate
10
 
11
  def if_node_exists(nodes, node_id):
12
  """
 
151
  st.error("Veuillez d'abord effectuer un audit pour visualiser le graphe de connaissance.")
152
  return
153
 
154
+ if "cr" not in st.session_state:
155
+ st.error("Veuillez d'abord effectuer un compte rendu pour visualiser le graphe de connaissance.")
156
+ return
157
+
158
  if "graph" not in st.session_state:
159
  st.session_state.graph = None
160
+
161
  st.title("Graphe de connaissance")
162
 
163
  if "node_types" not in st.session_state:
 
170
  st.session_state.chat_graph_history = []
171
 
172
  audit = st.session_state.audit_simplified
173
+ # content = st.session_state.audit["content"]
174
 
175
+ # if audit["type de fichier"] == "pdf":
176
+ # text = get_text_from_content_for_doc(content)
177
+ # elif audit["type de fichier"] == "audio":
178
+ # text = get_text_from_content_for_audio(content)
179
+
180
+ text = st.session_state.cr + "mots clés" + audit["Mots clés"]
181
 
182
  #summary_prompt = f"Voici un ensemble de documents : {text}. À partir de ces documents, veuillez fournir des résumés concis en vous concentrant sur l'extraction des relations essentielles et des événements. Il est crucial d'inclure les dates des actions ou des événements, car elles seront utilisées pour l'analyse chronologique. Par exemple : 'Sam a été licencié par le conseil d'administration d'OpenAI le 17 novembre 2023 (17 novembre, vendredi)', ce qui illustre la relation entre Sam et OpenAI ainsi que la date de l'événement."
183
 
 
187
  # st.session_state.summary = sum
188
 
189
  with st.spinner("Génération du graphe..."):
190
+ keywords_list = audit["Mots clés"].strip().split(",")
191
+ allowed_nodes_types =keywords_list+ ["Person","Organization","Location","Event","Date","Time","Ressource","Concept"]
192
+ graph = get_graph(text,allowed_nodes=allowed_nodes_types)
193
  st.session_state.graph = graph
194
 
195
  node_types = get_node_types(graph[0])
 
222
  with col2.container(border=True,height=800):
223
  st.markdown("##### Dialoguer avec le graphe")
224
 
225
+ user_query = st.chat_input("Par ici ...")
226
+ if user_query is not None and user_query != "":
227
+ st.session_state.chat_graph_history.append(HumanMessage(content=user_query))
228
+
229
+ with st.container(height=650, border=False):
230
+ for message in st.session_state.chat_graph_history:
231
+ if isinstance(message, AIMessage):
232
+ with st.chat_message("AI"):
233
+ st.markdown(message.content)
234
+ elif isinstance(message, HumanMessage):
235
+ with st.chat_message("Moi"):
236
+ st.write(message.content)
237
+
238
+ #check if last message is human message
239
+ if len(st.session_state.chat_graph_history) > 0:
240
+ last_message = st.session_state.chat_graph_history[-1]
241
+ if isinstance(last_message, HumanMessage):
242
+ with st.chat_message("AI"):
243
+ retreive = st.session_state.vectorstore.as_retriever()
244
+ context = retreive.invoke(last_message.content)
245
+ wrapped_prompt = f"Étant donné le contexte suivant {context}, et le graph de connaissance: {graph}, {last_message.content}"
246
+ response = st.write_stream(generate_response_via_langchain(wrapped_prompt,stream=True))
247
+ st.session_state.chat_graph_history.append(AIMessage(content=response))
248
+
249
+ if selected is not None:
250
+ with st.chat_message("AI"):
251
+ st.markdown(f" EXPLORER LES DONNEES CONTENUES DANS **{selected}**")
252
+
253
+ prompts = [f"Extrait moi toutes les informations du noeud ''{selected}'' ➡️",
254
+ f"Montre moi les conversations autour du noeud ''{selected}'' ➡️"]
255
+
256
+ for i,prompt in enumerate(prompts):
257
+ button = st.button(prompt,key=f"p_{i}",on_click=lambda i=i: st.session_state.chat_graph_history.append(HumanMessage(content=prompts[i])))
258
 
259
 
260
 
utils/audit/audit_doc.py CHANGED
@@ -170,8 +170,8 @@ def audit_descriptif_pdf(file,max_img_width) -> dict:
170
  text = " ".join([page["texte"] for page in doc_content.values()])
171
  key_words = extract_keywords(text)
172
  list_key_words_text = "\n".join(key_words[:10])
173
- prompt = f'''Voici une liste de mots et phrases provenant d'un document :
174
- - {list_key_words_text}
175
  Veuillez extraire les cinq mots clés les plus pertinents de cette liste. Chaque mot clé doit contenir au maximum deux mots.
176
 
177
  TA REPONSE DOIT RESPECTER LE FORMAT SUIVANT :
 
170
  text = " ".join([page["texte"] for page in doc_content.values()])
171
  key_words = extract_keywords(text)
172
  list_key_words_text = "\n".join(key_words[:10])
173
+ prompt = f'''Voici le document:
174
+ - {text}
175
  Veuillez extraire les cinq mots clés les plus pertinents de cette liste. Chaque mot clé doit contenir au maximum deux mots.
176
 
177
  TA REPONSE DOIT RESPECTER LE FORMAT SUIVANT :
utils/kg/construct_kg.py CHANGED
@@ -3,11 +3,14 @@ from langchain_experimental.graph_transformers import LLMGraphTransformer
3
  from langchain_openai import ChatOpenAI
4
  from langchain_core.documents import Document
5
 
6
- def get_graph(text):
7
 
8
  llm = ChatOpenAI(temperature=0, model_name="gpt-4o")
9
 
10
- llm_transformer = LLMGraphTransformer(llm=llm)
 
 
 
11
  documents = [Document(page_content=text)]
12
 
13
  graph_documents = llm_transformer.convert_to_graph_documents(documents)
 
3
  from langchain_openai import ChatOpenAI
4
  from langchain_core.documents import Document
5
 
6
+ def get_graph(text,allowed_nodes=None,prompt=None):
7
 
8
  llm = ChatOpenAI(temperature=0, model_name="gpt-4o")
9
 
10
+ if allowed_nodes:
11
+ llm_transformer = LLMGraphTransformer(llm=llm,allowed_nodes=allowed_nodes)
12
+ else:
13
+ llm_transformer = LLMGraphTransformer(llm=llm)
14
  documents = [Document(page_content=text)]
15
 
16
  graph_documents = llm_transformer.convert_to_graph_documents(documents)