import os import gradio as gr import requests from crewai import Agent, Task, Crew, Process from dotenv import load_dotenv from langchain_openai import ChatOpenAI from langchain_community.tools import DuckDuckGoSearchRun, DuckDuckGoSearchResults from crewai_tools import tool, SeleniumScrapingTool, ScrapeWebsiteTool from duckduckgo_search import DDGS from newspaper import Article load_dotenv() # Ensure essential environment variables are set openai_api_key = os.getenv('OPENAI_API_KEY') if not openai_api_key: raise EnvironmentError("OPENAI_API_KEY is not set in environment variables") def fetch_content(url): try: article = Article(url) article.download() article.parse() return article.text except Exception as e: print("ERROR: " + str(e)) return f"Error fetching content: {e}" # Define the DuckDuckGoSearch tool @tool('DuckDuckGoSearchResults') def search_results(search_query: str) -> dict: """ Effectue une recherche sur le Web pour rassembler et renvoyer une collection de résultats de recherche. Cet outil automatise la récupération d'informations Web liées à une requête spécifiée. Args : - search_query (str) : La chaîne de requête qui spécifie les informations à rechercher sur le Web. Il doit s'agir d'une expression claire et concise des besoins d'information de l'utilisateur. Retours : - list : Une liste de dictionnaires, où chaque dictionnaire représente un résultat de recherche. Chaque dictionnaire comprend un « extrait » de la page et le « lien » avec l'URL qui y renvoie. """ results = DDGS().text(search_query, max_results=5, timelimit='m') results_list = [{"title": result['title'], "snippet": result['body'], "link": result['href']} for result in results] return results_list @tool('WebScrapper') def web_scrapper(url: str, topic: str) -> str: """ Un outil conçu pour extraire et lire le contenu d'un lien spécifié et générer un résumé sur un sujet spécifique. Il est capable de gérer différents types de pages Web en effectuant des requêtes HTTP et en analysant le contenu HTML reçu. Cet outil est particulièrement utile pour les tâches de web scraping, la collecte de données ou l'extraction d'informations spécifiques à partir de sites Web. Args: - url (str) : L'URL à partir de laquelle récupérer le contenu. - topic (str) : Le sujet spécifique sur lequel générer un résumé. Returns: - summary (str): résumé de l'url sur le sujet """ # Scrape content from the specified URL content = fetch_content(url) # Prepare the prompt for generating the summary prompt = f"Générer un résumé du contenu suivant sur le sujet ## {topic} ### \n\nCONTENT:\n\n" + content # Generate the summary using OpenAI openai_llm = ChatOpenAI(temperature=0.4, model_name="gpt-3.5-turbo") response = openai_llm.invoke(prompt) summary_response = f"""### Summary: {response.content} URL: {url} ### """ return summary_response def kickoff_crew(topic: str, model_choice: str) -> str: try: # Initialize the OpenAI language model openai_llm = ChatOpenAI(temperature=0, model_name=model_choice) # Define Agents with OpenAI LLM researcher = Agent( role='Researcher', goal=f'Rechercher et collecter des informations détaillées sur le sujet ## {topic} ##', tools=[search_results, web_scrapper], llm=openai_llm, backstory=( "Vous êtes un chercheur méticuleux, habile à parcourir de grandes quantités d'informations pour en extraire des informations essentielles sur un sujet donné. " "Votre souci du détail garantit la fiabilité et l'exhaustivité de vos découvertes. " "Avec une approche stratégique, vous analysez et documentez soigneusement les données, dans le but de fournir des résultats précis et fiables." ), allow_delegation=False, max_iter=15, max_rpm=20, memory=True, verbose=True ) editor = Agent( role='Editor', goal=f'Compiler et affiner les informations dans un rapport complet sur le sujet ## {topic} ##', llm=openai_llm, backstory=( "En tant qu'éditeur expert, vous êtes spécialisé dans la transformation de données brutes en rapports clairs et attrayants. " "Votre maîtrise de la langue et votre souci du détail garantissent que chaque rapport ne transmet pas seulement des informations essentielles" "mais il est également facilement compréhensible et attrayant pour des publics divers." ), allow_delegation=False, max_iter=5, max_rpm=15, memory=True, verbose=True ) # Define Tasks research_task = Task( description=( f"Utilisez l'outil DuckDuckGoSearchResults pour collecter des extraits de recherche initiaux sur ## {topic} ##. " f"Si des recherches plus détaillées sont nécessaires, générez et exécutez de nouvelles requêtes liées à ## {topic} ##. " "Ensuite, utilisez l'outil WebScrapper pour approfondir les URL importantes identifiées à partir des extraits de code, en extrayant ainsi des informations et des insights supplémentaires. " "Compilez ces résultats dans un avant-projet, en documentant toutes les sources, titres et liens pertinents associés au sujet. " "Assurez une grande précision tout au long du processus et évitez toute fabrication ou fausse représentation des informations." ), expected_output=( "Un projet de rapport structuré sur le sujet, comprenant une introduction, un corps principal détaillé organisé par différents aspects du sujet et une conclusion. " "Chaque section doit citer correctement les sources, fournissant un aperçu complet des informations recueillies." ), agent=researcher ) edit_task = Task( description=( "Révisez et affinez le projet de rapport initial de la tâche de recherche. Organisez le contenu de manière logique pour améliorer le flux d'informations. " "Vérifiez l'exactitude de toutes les données, corrigez les écarts et mettez à jour les informations pour vous assurer qu'elles reflètent les connaissances actuelles et qu'elles sont bien étayées par les sources. " "Améliorez la lisibilité du rapport en améliorant la clarté du langage, en ajustant les structures de phrases et en maintenant un ton cohérent. " "Inclure une section répertoriant toutes les sources utilisées, formatée sous forme de puces suivant ce modèle : " "- titre : url'." ), expected_output=( f"Un rapport soigné et complet sur le sujet ## {topic} ##, avec un récit clair et professionnel qui reflète fidèlement les résultats de la recherche. " "Le rapport doit comprendre une introduction, une section de discussion approfondie, une conclusion concise et une liste de sources bien organisée. " "Assurez-vous que le document est grammaticalement correct et prêt à être publié ou présenté." ), agent=editor, context=[research_task] ) # Forming the Crew crew = Crew( agents=[researcher, editor], tasks=[research_task, edit_task], process=Process.sequential, ) # Kick-off the research process result = crew.kickoff() if not isinstance(result, str): result = str(result) return result except Exception as e: return f"Error: {str(e)}" def main(): """Set up the Gradio interface for the CrewAI Research Tool.""" with gr.Blocks() as demo: gr.Markdown("## Martian CrewAI Research Tool") topic_input = gr.Textbox(label="Entrer le sujet de recherche", placeholder="Écrivez le sujet ici..") model_choice = gr.Radio(choices=["gpt-3.5-turbo", "gpt-4"], label="Choissisez un modèle") submit_button = gr.Button("Commencez la Recherche!") output = gr.Markdown(label="Résultats") submit_button.click( fn=kickoff_crew, inputs=[topic_input, model_choice], outputs=output ) demo.launch(debug=True) if __name__ == "__main__": main()