First_agent_template / streamlit_app.py
KebabLover's picture
initial commit
ae04b8f
raw
history blame
14.1 kB
import streamlit as st
import os
import sys
import yaml
import datetime
import pytz
from typing import List, Dict, Any
# Ajout du répertoire courant au chemin Python pour importer les modules
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
# Import des composants nécessaires pour l'agent
from smolagents import CodeAgent
from smolagents.models import OpenAIServerModel, HfApiModel
from tools.final_answer import FinalAnswerTool
from tools.visit_webpage import VisitWebpageTool
from tools.web_search import DuckDuckGoSearchTool
from tools.shell_tool import ShellCommandTool
from tools.create_file_tool import CreateFileTool
from tools.modify_file_tool import ModifyFileTool
# Configuration de la page Streamlit
st.set_page_config(
page_title="Agent Conversationnel SmoLAgents 🤖",
page_icon="🤖",
layout="wide",
)
def initialize_agent(model_type="openai_server", model_config=None):
"""Initialise l'agent avec les outils et le modèle choisi
Args:
model_type: Type de modèle à utiliser ('openai_server', 'hf_api', etc.)
model_config: Configuration spécifique au modèle
"""
# Configuration du modèle en fonction du type choisi
if model_type == "openai_server":
# Configuration par défaut pour OpenAIServerModel
if model_config is None:
model_config = {
"api_base": "http://192.168.1.141:1234/v1",
"model_id": "Qwen/Qwen2.5-Coder-14B-Instruct-GGUF",
"api_key": "sk-dummy-key"
}
model = OpenAIServerModel(
api_base=model_config["api_base"],
model_id=model_config["model_id"],
api_key=model_config["api_key"]
)
elif model_type == "hf_api":
# Configuration par défaut pour HfApiModel
if model_config is None:
model_config = {
"model_id": "http://192.168.1.141:1234/v1",
"max_new_tokens": 2096,
"temperature": 0.5
}
model = HfApiModel(
model_id=model_config["model_id"],
max_new_tokens=model_config["max_new_tokens"],
temperature=model_config["temperature"]
)
elif model_type == "hf_cloud":
# Configuration pour HfApiModel avec un endpoint cloud
if model_config is None:
model_config = {
"model_id": "https://pflgm2locj2t89co.us-east-1.aws.endpoints.huggingface.cloud",
"max_new_tokens": 2096,
"temperature": 0.5
}
model = HfApiModel(
model_id=model_config["model_id"],
max_new_tokens=model_config["max_new_tokens"],
temperature=model_config["temperature"]
)
else:
st.error(f"Type de modèle non supporté: {model_type}")
return None
# Chargement des templates de prompt depuis le fichier YAML
try:
with open("prompts.yaml", 'r') as stream:
prompt_templates = yaml.safe_load(stream)
except:
st.error("Impossible de charger prompts.yaml. Utilisation des prompts par défaut.")
prompt_templates = None
# Initialisation des outils
final_answer = FinalAnswerTool()
# Création de l'agent avec les mêmes outils que dans app.py
agent = CodeAgent(
model=model,
tools=[
final_answer,
DuckDuckGoSearchTool(),
VisitWebpageTool(),
ShellCommandTool(),
CreateFileTool(),
ModifyFileTool()
],
max_steps=6,
verbosity_level=1,
grammar=None,
planning_interval=None,
name=None,
description=None,
prompt_templates=prompt_templates
)
return agent
def format_step_message(step, is_final=False):
"""Formate les messages de l'agent pour l'affichage dans Streamlit"""
if hasattr(step, "model_output") and step.model_output:
# Nettoyer et formater la sortie du modèle pour l'affichage
content = step.model_output.strip()
if not is_final:
return content
else:
return f"**Réponse finale :** {content}"
if hasattr(step, "observations") and step.observations:
# Afficher les observations des outils
return f"**Observations :** {step.observations.strip()}"
if hasattr(step, "error") and step.error:
# Afficher les erreurs
return f"**Erreur :** {step.error}"
# Cas par défaut
return str(step)
def process_user_input(agent, user_input):
"""Traite l'entrée utilisateur avec l'agent et renvoie les résultats étape par étape"""
# Vérification de la connexion au serveur LLM
try:
# Exécution de l'agent et capture des étapes
with st.spinner("L'agent réfléchit..."):
# Placeholder pour la sortie de l'agent
response_container = st.container()
# Exécution de l'agent et capture des étapes
steps = []
final_step = None
with response_container:
step_container = st.empty()
step_text = ""
# Exécute l'agent et capture les étapes de manière incrémentale
for step in agent.run(user_input, stream=True):
steps.append(step)
# Mettre à jour l'affichage des étapes
step_number = f"Étape {step.step_number}" if hasattr(step, "step_number") and step.step_number is not None else ""
step_content = format_step_message(step)
# Ajouter au texte des étapes
if step_number:
step_text += f"### {step_number}\n\n"
step_text += f"{step_content}\n\n---\n\n"
# Mettre à jour l'affichage
step_container.markdown(step_text)
# Conserver la dernière étape pour la réponse finale
final_step = step
# Afficher la réponse finale
if final_step:
final_answer = format_step_message(final_step, is_final=True)
st.markdown(f"## Réponse Finale\n\n{final_answer}")
return final_step
except Exception as e:
st.error(f"Erreur lors de l'exécution de l'agent: {str(e)}")
return None
def main():
st.title("Agent Conversationnel SmoLAgents 🤖")
st.markdown("""
Bienvenue! Cet agent utilise SmoLAgents pour se connecter à un modèle de langage.
Posez vos questions ci-dessous.
""")
# Sidebar pour la configuration du modèle
with st.sidebar:
st.title("Configuration du Modèle")
# Sélectionner le type de modèle
model_type = st.selectbox(
"Type de modèle",
["openai_server", "hf_api", "hf_cloud"],
index=0,
help="Choisissez le type de modèle à utiliser avec l'agent"
)
# Configuration spécifique en fonction du type de modèle
model_config = {}
if model_type == "openai_server":
st.subheader("Configuration OpenAI Server")
model_config["api_base"] = st.text_input(
"URL du serveur",
value="http://192.168.1.141:1234/v1",
help="Adresse du serveur OpenAI compatible"
)
model_config["model_id"] = st.text_input(
"ID du modèle",
value="Qwen/Qwen2.5-Coder-14B-Instruct-GGUF",
help="Identifiant du modèle local"
)
model_config["api_key"] = st.text_input(
"Clé API",
value="sk-dummy-key",
type="password",
help="Clé API pour le serveur (dummy pour LMStudio)"
)
elif model_type == "hf_api":
st.subheader("Configuration Hugging Face API")
model_config["model_id"] = st.text_input(
"URL du modèle",
value="http://192.168.1.141:1234/v1",
help="URL du modèle ou endpoint"
)
model_config["max_new_tokens"] = st.slider(
"Tokens maximum",
min_value=512,
max_value=4096,
value=2096,
help="Nombre maximum de tokens à générer"
)
model_config["temperature"] = st.slider(
"Température",
min_value=0.1,
max_value=1.0,
value=0.5,
step=0.1,
help="Température pour la génération (plus élevée = plus créatif)"
)
elif model_type == "hf_cloud":
st.subheader("Configuration Hugging Face Cloud")
model_config["model_id"] = st.text_input(
"URL du endpoint cloud",
value="https://pflgm2locj2t89co.us-east-1.aws.endpoints.huggingface.cloud",
help="URL de l'endpoint cloud Hugging Face"
)
model_config["max_new_tokens"] = st.slider(
"Tokens maximum",
min_value=512,
max_value=4096,
value=2096,
help="Nombre maximum de tokens à générer"
)
model_config["temperature"] = st.slider(
"Température",
min_value=0.1,
max_value=1.0,
value=0.5,
step=0.1,
help="Température pour la génération (plus élevée = plus créatif)"
)
# Bouton pour réinitialiser l'agent avec la nouvelle configuration
if st.button("Appliquer la configuration"):
with st.spinner("Initialisation de l'agent avec le nouveau modèle..."):
st.session_state.agent = initialize_agent(model_type, model_config)
st.success("✅ Configuration appliquée avec succès!")
# Vérifier la connexion au serveur
if model_type == "openai_server":
llm_api_url = model_config["api_base"].split("/v1")[0]
try:
import requests
response = requests.get(f"{llm_api_url}/health", timeout=2)
if response.status_code == 200:
st.success("✅ Connexion au serveur LLM établie")
else:
st.warning("⚠️ Le serveur LLM est accessible mais renvoie un statut non-OK")
except Exception:
st.error("❌ Impossible de se connecter au serveur LLM. Vérifiez que le serveur est en cours d'exécution à l'adresse spécifiée.")
# Initialisation de l'agent si ce n'est pas déjà fait
if "agent" not in st.session_state:
with st.spinner("Initialisation de l'agent..."):
st.session_state.agent = initialize_agent(model_type, model_config)
# Initialisation de l'historique de conversation
if "messages" not in st.session_state:
st.session_state.messages = [
{"role": "assistant", "content": "Bonjour! Comment puis-je vous aider aujourd'hui?"}
]
# Affichage de l'historique des messages
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.markdown(message["content"])
# Zone de saisie utilisateur
if prompt := st.chat_input("Posez votre question..."):
# Ajouter la question de l'utilisateur à l'historique
st.session_state.messages.append({"role": "user", "content": prompt})
# Afficher la question de l'utilisateur
with st.chat_message("user"):
st.markdown(prompt)
# Traiter la demande avec l'agent
with st.chat_message("assistant"):
response = process_user_input(st.session_state.agent, prompt)
if response and hasattr(response, "model_output"):
# Ajouter la réponse à l'historique
st.session_state.messages.append({"role": "assistant", "content": response.model_output})
# Bouton pour effacer l'historique
if st.sidebar.button("Nouvelle conversation"):
st.session_state.messages = [
{"role": "assistant", "content": "Bonjour! Comment puis-je vous aider aujourd'hui?"}
]
st.rerun()
# Afficher des informations supplémentaires dans la barre latérale
with st.sidebar:
st.title("À propos de cet agent")
st.markdown("""
Cet agent utilise SmoLAgents pour se connecter à un modèle de langage hébergé localement.
### Outils disponibles
- Recherche web (DuckDuckGo)
- Visite de pages web
- Exécution de commandes shell
- Création et modification de fichiers
### Configuration
Utilisez les options ci-dessus pour configurer le modèle de langage.
### Problèmes courants
- Si l'agent ne répond pas, vérifiez que le serveur LLM est en cours d'exécution et accessible.
- Assurez-vous que toutes les dépendances sont installées via `pip install -r requirements.txt`.
""")
# Afficher l'heure actuelle dans différents fuseaux horaires
st.subheader("Heure actuelle")
selected_timezone = st.selectbox(
"Choisissez un fuseau horaire",
["Europe/Paris", "America/New_York", "Asia/Tokyo", "Australia/Sydney"]
)
tz = pytz.timezone(selected_timezone)
local_time = datetime.datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S")
st.write(f"L'heure actuelle à {selected_timezone} est: {local_time}")
if __name__ == "__main__":
main()