Update app.py
Browse files
app.py
CHANGED
|
@@ -33,10 +33,19 @@ from agent_collaboratif_avid import (
|
|
| 33 |
MAX_VALIDATION_LOOPS
|
| 34 |
)
|
| 35 |
import bcrypt
|
| 36 |
-
from chainlit.data.sql_alchemy import SQLAlchemyDataLayer
|
|
|
|
| 37 |
from supabase import create_client, Client
|
| 38 |
from supabase.lib.client_options import ClientOptions
|
| 39 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 40 |
SUPABASE_URL = os.environ.get("SUPABASE_URL")
|
| 41 |
SUPABASE_ANON_KEY = os.environ.get("SUPABASE_ANON_KEY")
|
| 42 |
CONNINFO = os.environ.get("CONNINFO")
|
|
@@ -45,6 +54,16 @@ url: str = SUPABASE_URL
|
|
| 45 |
key: str = SUPABASE_ANON_KEY
|
| 46 |
supabase: Client = create_client(url, key)
|
| 47 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 48 |
# =============================================================================
|
| 49 |
# CONFIGURATION DE L'AUTHENTIFICATION (Optionnel)
|
| 50 |
# =============================================================================
|
|
@@ -73,10 +92,6 @@ def auth_callback(username: str, password: str) -> Optional[cl.User]:
|
|
| 73 |
break
|
| 74 |
return None
|
| 75 |
|
| 76 |
-
@cl.data_layer
|
| 77 |
-
def get_data_layer():
|
| 78 |
-
return SQLAlchemyDataLayer(conninfo=CONNINFO, storage_provider=supabase)
|
| 79 |
-
|
| 80 |
# =============================================================================
|
| 81 |
# CONFIGURATION LANGSMITH
|
| 82 |
# =============================================================================
|
|
@@ -202,6 +217,33 @@ async def display_similar_info(similar_info: List[Dict[str, Any]]):
|
|
| 202 |
elements=elements
|
| 203 |
).send()
|
| 204 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 205 |
# =============================================================================
|
| 206 |
# FONCTIONS D'AFFICHAGE STREAMING PAR NŒUD
|
| 207 |
# =============================================================================
|
|
@@ -268,7 +310,8 @@ async def process_query_with_tracing(query: str, thread_id: str) -> Dict[str, An
|
|
| 268 |
"iteration_count": 0,
|
| 269 |
"errors": [],
|
| 270 |
"additional_information": [],
|
| 271 |
-
"similar_info_response":""
|
|
|
|
| 272 |
}
|
| 273 |
|
| 274 |
# Message de démarrage
|
|
@@ -279,6 +322,8 @@ async def process_query_with_tracing(query: str, thread_id: str) -> Dict[str, An
|
|
| 279 |
|
| 280 |
# STREAMING: Utilisation de app.astream() pour obtenir les mises à jour après chaque nœud
|
| 281 |
try:
|
|
|
|
|
|
|
| 282 |
async for event in app.astream(initial_state):
|
| 283 |
# event est un dictionnaire avec les nœuds comme clés
|
| 284 |
for node_name, node_state in event.items():
|
|
@@ -330,8 +375,9 @@ async def process_query_with_tracing(query: str, thread_id: str) -> Dict[str, An
|
|
| 330 |
"errors": final_state.get("errors", []),
|
| 331 |
"additional_information": final_state.get("additional_information", []),
|
| 332 |
"similar_info_response": final_state.get("similar_info_response", ""),
|
|
|
|
| 333 |
"sources_used": [
|
| 334 |
-
info["database"]
|
| 335 |
for info in final_state.get("collected_information", [])
|
| 336 |
],
|
| 337 |
"pinecone_index": PINECONE_INDEX_NAME
|
|
@@ -487,6 +533,14 @@ async def main(message: cl.Message):
|
|
| 487 |
await stream_response(result["similar_info_response"], similar_msg, chunk_size=50)
|
| 488 |
|
| 489 |
#await display_similar_info(result["similar_info_response"])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 490 |
|
| 491 |
# Métadonnées
|
| 492 |
metadata_parts = [
|
|
|
|
| 33 |
MAX_VALIDATION_LOOPS
|
| 34 |
)
|
| 35 |
import bcrypt
|
| 36 |
+
#from chainlit.data.sql_alchemy import SQLAlchemyDataLayer
|
| 37 |
+
from sql_alchemy import SQLAlchemyDataLayer
|
| 38 |
from supabase import create_client, Client
|
| 39 |
from supabase.lib.client_options import ClientOptions
|
| 40 |
|
| 41 |
+
#from langfuse.langchain import CallbackHandler
|
| 42 |
+
#import getpass
|
| 43 |
+
#os.environ['LANGFUSE_SECRET_KEY'] = getpass.getpass("Enter your Secret key: ")
|
| 44 |
+
#os.environ['LANGFUSE_PUBLIC_KEY'] = getpass.getpass("Enter your Public key: ")
|
| 45 |
+
#os.environ["LANGFUSE_HOST"] = "https://cloud.langfuse.com"
|
| 46 |
+
#langfuse_handler = CallbackHandler()
|
| 47 |
+
|
| 48 |
+
|
| 49 |
SUPABASE_URL = os.environ.get("SUPABASE_URL")
|
| 50 |
SUPABASE_ANON_KEY = os.environ.get("SUPABASE_ANON_KEY")
|
| 51 |
CONNINFO = os.environ.get("CONNINFO")
|
|
|
|
| 54 |
key: str = SUPABASE_ANON_KEY
|
| 55 |
supabase: Client = create_client(url, key)
|
| 56 |
|
| 57 |
+
#url: str = "https://urtvfyesitnmwrouarze.supabase.co"
|
| 58 |
+
#key: str = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InVydHZmeWVzaXRubXdyb3VhcnplIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTk5NTgyNzIsImV4cCI6MjA3NTUzNDI3Mn0.HvZVdlyyck6iI6L5XiPupPZ8voLt-u4NCKAqgwHl6dE"
|
| 59 |
+
#supabase: Client = create_client(url, key, options=ClientOptions(auto_refresh_token=False,persist_session=True))
|
| 60 |
+
#@cl.data_layer
|
| 61 |
+
#def get_data_layer():
|
| 62 |
+
# return SQLAlchemyDataLayer(conninfo="postgresql+asyncpg://postgres.urtvfyesitnmwrouarze:2VlIHUmI3qVhJpcb@aws-1-eu-north-1.pooler.supabase.com:5432/postgres", storage_provider=supabase)
|
| 63 |
+
@cl.data_layer
|
| 64 |
+
def get_data_layer():
|
| 65 |
+
return SQLAlchemyDataLayer(conninfo=CONNINFO, storage_provider=supabase)
|
| 66 |
+
|
| 67 |
# =============================================================================
|
| 68 |
# CONFIGURATION DE L'AUTHENTIFICATION (Optionnel)
|
| 69 |
# =============================================================================
|
|
|
|
| 92 |
break
|
| 93 |
return None
|
| 94 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 95 |
# =============================================================================
|
| 96 |
# CONFIGURATION LANGSMITH
|
| 97 |
# =============================================================================
|
|
|
|
| 217 |
elements=elements
|
| 218 |
).send()
|
| 219 |
|
| 220 |
+
async def display_web_search_results(web_search_results: List[Dict[str, Any]]):
|
| 221 |
+
"""Affiche les résultats de recherche web."""
|
| 222 |
+
if not web_search_results:
|
| 223 |
+
return
|
| 224 |
+
|
| 225 |
+
elements = []
|
| 226 |
+
content_parts = []
|
| 227 |
+
content_parts.append(f"### 🌐 Résultats de la recherche web\n")
|
| 228 |
+
content_parts.append(f"**Nombre de résultats:** {len(web_search_results)}\n")
|
| 229 |
+
|
| 230 |
+
for idx, item in enumerate(web_search_results[:5], 1): # Limiter à 5 résultats
|
| 231 |
+
content_parts.append(f"**{idx}. Titre:** {item['title']}")
|
| 232 |
+
content_parts.append(f"**Lien:** {item['markdown_link']}")
|
| 233 |
+
content_parts.append(f"**Résumé:** {item['summary']}\n")
|
| 234 |
+
|
| 235 |
+
element = cl.Text(
|
| 236 |
+
content="\n".join(content_parts),
|
| 237 |
+
display="side"
|
| 238 |
+
)
|
| 239 |
+
elements.append(element)
|
| 240 |
+
|
| 241 |
+
if elements:
|
| 242 |
+
await cl.Message(
|
| 243 |
+
content="🌐 **Informations trouvées sur le web**",
|
| 244 |
+
elements=elements
|
| 245 |
+
).send()
|
| 246 |
+
|
| 247 |
# =============================================================================
|
| 248 |
# FONCTIONS D'AFFICHAGE STREAMING PAR NŒUD
|
| 249 |
# =============================================================================
|
|
|
|
| 310 |
"iteration_count": 0,
|
| 311 |
"errors": [],
|
| 312 |
"additional_information": [],
|
| 313 |
+
"similar_info_response":"",
|
| 314 |
+
"web_search_results": []
|
| 315 |
}
|
| 316 |
|
| 317 |
# Message de démarrage
|
|
|
|
| 322 |
|
| 323 |
# STREAMING: Utilisation de app.astream() pour obtenir les mises à jour après chaque nœud
|
| 324 |
try:
|
| 325 |
+
#async for event in app.astream(initial_state, {"callbacks": [langfuse_handler]}):
|
| 326 |
+
#app.invoke(intial_state, config={"callbacks": [langfuse_handler]})
|
| 327 |
async for event in app.astream(initial_state):
|
| 328 |
# event est un dictionnaire avec les nœuds comme clés
|
| 329 |
for node_name, node_state in event.items():
|
|
|
|
| 375 |
"errors": final_state.get("errors", []),
|
| 376 |
"additional_information": final_state.get("additional_information", []),
|
| 377 |
"similar_info_response": final_state.get("similar_info_response", ""),
|
| 378 |
+
"web_search_results": final_state.get("web_search_results", []),
|
| 379 |
"sources_used": [
|
| 380 |
+
info["database"]
|
| 381 |
for info in final_state.get("collected_information", [])
|
| 382 |
],
|
| 383 |
"pinecone_index": PINECONE_INDEX_NAME
|
|
|
|
| 533 |
await stream_response(result["similar_info_response"], similar_msg, chunk_size=50)
|
| 534 |
|
| 535 |
#await display_similar_info(result["similar_info_response"])
|
| 536 |
+
|
| 537 |
+
# Afficher les résultats de recherche web collectés par le nœud 7
|
| 538 |
+
web_msg = cl.Message(content="Résultats de recherche complémentaires sur le web : \n\n")
|
| 539 |
+
await web_msg.send()
|
| 540 |
+
for result_web in result["web_search_results"]:
|
| 541 |
+
web_search = "- " + result_web['markdown_link'] + " : " + result_web['summary'] + "\n\n"
|
| 542 |
+
await stream_response(web_search, web_msg, chunk_size=50)
|
| 543 |
+
#await display_web_search_results(result["web_search_results"])
|
| 544 |
|
| 545 |
# Métadonnées
|
| 546 |
metadata_parts = [
|