import os import ast import streamlit as st from crewai import Agent, Crew, Process, Task from crewai_tools import SerperDevTool from langchain_google_genai import ChatGoogleGenerativeAI from crewai import LLM from typing import List # Configuration des clés API import os os.environ["GEMINI_API_KEY"] = os.environ.get("GEMINI_API_KEY") os.environ["SERPER_API_KEY"] = os.environ.get("SERPER_API_KEY") llm = LLM( model="gemini/gemini-1.5-flash", temperature=0.7, timeout=120, max_tokens=8000, ) search_tool = SerperDevTool() # Définitions des agents avec outils explicites project_manager = Agent( role="Chef de Projet", goal="Coordonner les autres agents et synthétiser les résultats.", backstory="Un chef de projet expérimenté avec une expertise dans la gestion d'équipes et la coordination de projets complexes.", llm=llm, verbose=True, allow_delegation=True, tools=[search_tool] ) topic_analyst = Agent( role="Analyste de Thème", goal="Analyser le thème et générer un plan détaillé.", backstory="Un expert en recherche et en structuration de contenu.", llm=llm, verbose=True, tools=[search_tool] ) content_writer = Agent( role="Rédacteur de Contenu", goal="Rédiger le contenu en se basant sur des recherches approfondies.", backstory="Un rédacteur spécialisé dans la création de contenu académique.", llm=llm, verbose=True, tools=[search_tool] ) editor = Agent( role="Éditeur", goal="Réviser et harmoniser le contenu final.", backstory="Un éditeur expérimenté avec un excellent sens du détail.", llm=llm, verbose=True, tools=[search_tool] ) def create_outline_task(topic: str) -> Task: return Task( description=f"""Crée un plan détaillé pour un exposé sur '{topic}'. Réponds UNIQUEMENT avec une liste Python. Format attendu: ['Introduction', 'I', 'II','etc..', 'Conclusion']""", expected_output="Liste Python des sections de l'exposé sous forme de string", agent=topic_analyst ) def create_content_task(topic: str, section: str, outline_task: Task) -> Task: return Task( description=f"""Rédige la section '{section}' de l'exposé sur '{topic}'. Utilise un style académique et professionnel. Base-toi sur des recherches récentes et pertinentes. Format attendu: Texte en Markdown avec des sous-titres si nécessaire.""", expected_output="Contenu de la section en format Markdown", agent=content_writer, context=[outline_task] ) def create_editing_task(content_tasks: List[Task]) -> Task: return Task( description="""Révise et harmonise l'ensemble du contenu. Assure la cohérence du style et la qualité de l'écriture. Format attendu: Texte final en Markdown.""", expected_output="Version finale de l'exposé en format Markdown", agent=editor, context=content_tasks ) # Interface Streamlit st.title("🤖 Générateur d'Exposés avec CrewAI") topic = st.text_input("Entrez le thème de l'exposé:", "L'Intelligence Artificielle en 2024") if st.button("Générer l'exposé"): try: with st.spinner("1/4 - Création du plan..."): # Étape 1: Création du plan outline_task = create_outline_task(topic) outline_crew = Crew( agents=[topic_analyst], tasks=[outline_task], process=Process.sequential, verbose=True ) outline_result = outline_crew.kickoff() # Parsing du résultat try: sections = eval(outline_result.raw.strip('"\'')) st.write("Plan généré:", sections) except Exception as e: st.error(f"Erreur lors du parsing du plan: {e}") st.stop() with st.spinner("2/4 - Rédaction des sections..."): # Étape 2: Création du contenu section par section content_tasks = [] content_results = [] for section in sections: task = create_content_task(topic, section, outline_task) content_crew = Crew( agents=[content_writer], tasks=[task], process=Process.sequential, verbose=True ) result = content_crew.kickoff() content_tasks.append(task) content_results.append(result.raw) st.write(f"Section '{section}' rédigée.") with st.spinner("3/4 - Révision finale..."): # Étape 3: Édition finale editing_task = create_editing_task(content_tasks) editing_crew = Crew( agents=[editor], tasks=[editing_task], process=Process.sequential, verbose=True ) final_result = editing_crew.kickoff() with st.spinner("4/4 - Assemblage final..."): # Étape 4: Assemblage et présentation st.success("Exposé généré avec succès!") st.markdown(final_result.raw) except Exception as e: st.error(f"Une erreur est survenue: {e}") st.stop()