import os from langchain_openai import ChatOpenAI from langchain_core.prompts import ChatPromptTemplate from langchain_core.output_parsers import StrOutputParser from langgraph.graph import StateGraph, END from typing import TypedDict, Annotated, List import operator from langchain_core.messages import BaseMessage, HumanMessage from dotenv import load_dotenv from sockets import socketio import time load_dotenv() api_key = os.getenv("OPENAI_API_KEY") if not api_key: api_key = "YOUR_API_KEY_HERE" os.environ["OPENAI_API_KEY"] = api_key class AgentState(TypedDict): messages: Annotated[List[BaseMessage], operator.add] def stream_message(step, message): for char in message: socketio.emit('stream', {'step': step, 'data': char}) time.sleep(0.01) socketio.emit('stream_end', {'step': step}) def retrieve_job_offers(state): stream_message("Récupération des offres d'emploi", "Analyse des offres d'emploi pour le métier de responsable marketing...") return {"messages": [HumanMessage(content="Job offers retrieved")]} def retrieve_job_stats(state): stream_message("Récupération des statistiques de l'emploi", "Analyse des statistiques de l'emploi pour le métier de responsable marketing...") return {"messages": [HumanMessage(content="Job stats retrieved")]} def retrieve_job_description(state): stream_message("Récupération de la fiche métier", "Récupération de la fiche métier de responsable marketing depuis France Compétences...") return {"messages": [HumanMessage(content="Job description retrieved")]} def generate_sector_rating(state): steps = [ "Description du secteur : Le secteur du marketing est en pleine expansion...", "Description des OPCOs : Les principaux OPCOs sont l'OPCO Atlas...", "Description des missions : Le responsable marketing définit la stratégie marketing...", "Description des activités professionnelles : Cela inclut la gestion de campagnes...", "Description des compétences professionnelles : Maîtrise des outils d'analyse...", "Liste des 5 métiers les plus recrutés : 1. Responsable marketing...", "Les plus et les moins du métier : Avantages : missions variées...", "Tensions sur les recrutements : Forte tension sur les profils digitaux..." ] for step_content in steps: stream_message("Génération de la cotation du secteur", step_content) return {"messages": [HumanMessage(content="Sector rating generated")]} workflow = StateGraph(AgentState) workflow.add_node("retrieve_job_offers", retrieve_job_offers) workflow.add_node("retrieve_job_stats", retrieve_job_stats) workflow.add_node("retrieve_job_description", retrieve_job_description) workflow.add_node("generate_sector_rating", generate_sector_rating) workflow.set_entry_point("retrieve_job_offers") workflow.add_edge("retrieve_job_offers", "retrieve_job_stats") workflow.add_edge("retrieve_job_stats", "retrieve_job_description") workflow.add_edge("retrieve_job_description", "generate_sector_rating") workflow.add_edge("generate_sector_rating", END) rac_graph_agent = workflow.compile()