KebabLover commited on
Commit
ae04b8f
·
1 Parent(s): ae7a494

initial commit

Browse files
.gradio/certificate.pem ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -----BEGIN CERTIFICATE-----
2
+ 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
31
+ -----END CERTIFICATE-----
README.md CHANGED
@@ -15,4 +15,113 @@ tags:
15
  - agent-course
16
  ---
17
 
18
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  - agent-course
16
  ---
17
 
18
+ # Simple Local Agent 🤖
19
+
20
+ Un agent conversationnel simple utilisant SmoLAgents pour se connecter à un modèle de langage, que ce soit via un serveur local (LMStudio) ou via d'autres APIs.
21
+
22
+ ## Prérequis 📋
23
+
24
+ - Python 3.8+
25
+ - Un modèle de langage hébergé localement ou accessible via une API
26
+
27
+ ## Installation ⚙️
28
+
29
+ 1. Installez les dépendances requises :
30
+
31
+ ```bash
32
+ pip install -r requirements.txt
33
+ ```
34
+
35
+ ## Utilisation 💻
36
+
37
+ ### Interface Gradio
38
+
39
+ 1. Assurez-vous que votre serveur LLM est en cours d'exécution à l'adresse spécifiée.
40
+
41
+ 2. Lancez l'agent avec l'interface Gradio :
42
+
43
+ ```bash
44
+ python app.py
45
+ ```
46
+
47
+ ### Interface Streamlit (Nouvelle !)
48
+
49
+ Nous avons également ajouté une interface Streamlit qui offre plus de flexibilité et d'options de configuration :
50
+
51
+ 1. Lancez l'application Streamlit :
52
+
53
+ ```bash
54
+ streamlit run streamlit_app.py
55
+ ```
56
+
57
+ 2. Accédez à l'interface via votre navigateur web (généralement à l'adresse http://localhost:8501).
58
+
59
+ ### Fonctionnalités de l'interface Streamlit
60
+
61
+ - **Interface de chat interactive** pour discuter avec l'agent
62
+ - **Choix entre différents types de modèles** :
63
+ - OpenAI Server (LMStudio ou autre serveur compatible OpenAI)
64
+ - Hugging Face API
65
+ - Hugging Face Cloud
66
+ - **Configuration personnalisable** pour chaque type de modèle
67
+ - **Affichage en temps réel** du raisonnement de l'agent
68
+ - **Informations utiles** dans la barre latérale
69
+
70
+ ## Configuration ⚙️
71
+
72
+ ### Configuration du modèle
73
+
74
+ L'interface Streamlit permet de configurer facilement le modèle sans modifier le code source :
75
+
76
+ - **OpenAI Server** : URL du serveur, ID du modèle, clé API
77
+ - **Hugging Face API** : URL du modèle, tokens maximum, température
78
+ - **Hugging Face Cloud** : URL de l'endpoint, tokens maximum, température
79
+
80
+ ### Configuration des outils
81
+
82
+ L'agent est équipé de plusieurs outils puissants qui lui permettent d'interagir avec le monde extérieur et d'effectuer diverses actions :
83
+
84
+ #### Outils principaux intégrés
85
+
86
+ - **DuckDuckGoSearchTool** : Permet à l'agent d'effectuer des recherches web via DuckDuckGo pour obtenir des informations à jour sur n'importe quel sujet.
87
+ - **VisitWebpageTool** : Permet à l'agent de visiter une page web spécifique et d'en extraire le contenu pour analyse.
88
+ - **ShellCommandTool** : Donne à l'agent la capacité d'exécuter des commandes shell sur le système hôte (avec les précautions de sécurité appropriées).
89
+ - **CreateFileTool** : Permet à l'agent de créer de nouveaux fichiers dans le système.
90
+ - **ModifyFileTool** : Permet à l'agent de modifier des fichiers existants.
91
+ - **FinalAnswerTool** : Fournit une réponse finale structurée à l'utilisateur, résumant les informations trouvées.
92
+
93
+ #### Outils personnalisés
94
+
95
+ L'agent inclut également quelques outils personnalisés :
96
+
97
+ - **get_current_realtime** : Renvoie l'heure actuelle du système.
98
+ - **get_current_time_in_timezone** : Récupère l'heure locale actuelle dans un fuseau horaire spécifié (par exemple, "Europe/Paris", "America/New_York").
99
+
100
+ #### Extensibilité
101
+
102
+ L'architecture de l'agent est conçue pour être facilement extensible. Vous pouvez ajouter vos propres outils personnalisés en suivant le modèle d'exemple dans le fichier `app.py` :
103
+
104
+ ```python
105
+ @tool
106
+ def my_custom_tool(arg1: str, arg2: int) -> str:
107
+ """Description de ce que fait l'outil
108
+ Args:
109
+ arg1: description du premier argument
110
+ arg2: description du second argument
111
+ """
112
+ # Implémentation de votre outil
113
+ return "Résultat de l'outil"
114
+ ```
115
+
116
+ ## Exemples d'utilisation
117
+
118
+ Voici quelques exemples de questions que vous pouvez poser à l'agent :
119
+
120
+ - "Quelle est l'heure actuelle à Tokyo ?"
121
+ - "Peux-tu me faire un résumé des dernières nouvelles sur l'IA ?"
122
+ - "Crée un fichier contenant un exemple de code Python pour trier une liste"
123
+ - "Explique-moi comment fonctionne la technologie des transformers en IA"
124
+
125
+ ---
126
+
127
+ *Consultez la référence de configuration sur https://huggingface.co/docs/hub/spaces-config-reference* 🌐
app.py CHANGED
@@ -4,8 +4,13 @@ import requests
4
  import pytz
5
  import yaml
6
  from tools.final_answer import FinalAnswerTool
7
-
 
8
  from Gradio_UI import GradioUI
 
 
 
 
9
 
10
  # Below is an example of a tool that does nothing. Amaze us with your creativity !
11
  @tool
@@ -18,6 +23,13 @@ def my_custom_tool(arg1:str, arg2:int)-> str: #it's import to specify the return
18
  """
19
  return "What magic will you build ?"
20
 
 
 
 
 
 
 
 
21
  @tool
22
  def get_current_time_in_timezone(timezone: str) -> str:
23
  """A tool that fetches the current local time in a specified timezone.
@@ -37,15 +49,21 @@ def get_current_time_in_timezone(timezone: str) -> str:
37
  final_answer = FinalAnswerTool()
38
 
39
  # If the agent does not answer, the model is overloaded, please use another model or the following Hugging Face Endpoint that also contains qwen2.5 coder:
40
- # model_id='https://pflgm2locj2t89co.us-east-1.aws.endpoints.huggingface.cloud'
41
 
42
- model = HfApiModel(
43
- max_tokens=2096,
44
- temperature=0.5,
45
- model_id='Qwen/Qwen2.5-Coder-32B-Instruct',# it is possible that this model may be overloaded
46
- custom_role_conversions=None,
47
- )
 
 
 
 
 
48
 
 
49
 
50
  # Import tool from Hub
51
  image_generation_tool = load_tool("agents-course/text-to-image", trust_remote_code=True)
@@ -55,7 +73,7 @@ with open("prompts.yaml", 'r') as stream:
55
 
56
  agent = CodeAgent(
57
  model=model,
58
- tools=[final_answer], ## add your tools here (don't remove final answer)
59
  max_steps=6,
60
  verbosity_level=1,
61
  grammar=None,
 
4
  import pytz
5
  import yaml
6
  from tools.final_answer import FinalAnswerTool
7
+ from tools.visit_webpage import VisitWebpageTool
8
+ from tools.web_search import DuckDuckGoSearchTool
9
  from Gradio_UI import GradioUI
10
+ from smolagents.models import OpenAIServerModel
11
+ from tools.shell_tool import ShellCommandTool
12
+ from tools.create_file_tool import CreateFileTool
13
+ from tools.modify_file_tool import ModifyFileTool
14
 
15
  # Below is an example of a tool that does nothing. Amaze us with your creativity !
16
  @tool
 
23
  """
24
  return "What magic will you build ?"
25
 
26
+ # Below is an example of a tool that does nothing. Amaze us with your creativity !
27
+ @tool
28
+ def get_current_realtime()-> str: #it's import to specify the return type
29
+ #Keep this format for the description / args / args description but feel free to modify the tool
30
+ """A tool that get the current realtime
31
+ """
32
+ return datetime.datetime.now()
33
  @tool
34
  def get_current_time_in_timezone(timezone: str) -> str:
35
  """A tool that fetches the current local time in a specified timezone.
 
49
  final_answer = FinalAnswerTool()
50
 
51
  # If the agent does not answer, the model is overloaded, please use another model or the following Hugging Face Endpoint that also contains qwen2.5 coder:
52
+ # model_id='https://pflgm2locj2t89co.us-east-1.aws.endpoints.huggingface.cloud' è
53
 
54
+ # model = HfApiModel(
55
+ # model_id="http://192.168.1.141:1234/v1",
56
+ # max_new_tokens=2096,
57
+ # temperature=0.5
58
+ # )
59
+ # Configuration du modèle pour se connecter au LLM hébergé localement via LMStudio
60
+ model = OpenAIServerModel(
61
+ api_base ="http://192.168.1.141:1234/v1",
62
+ model_id="Qwen/Qwen2.5-Coder-14B-Instruct-GGUF", # Nom arbitraire pour le modèle local
63
+ api_key="sk-dummy-key" # Clé factice pour LMStudio
64
+ # max_tokens=2096,
65
 
66
+ )
67
 
68
  # Import tool from Hub
69
  image_generation_tool = load_tool("agents-course/text-to-image", trust_remote_code=True)
 
73
 
74
  agent = CodeAgent(
75
  model=model,
76
+ tools=[final_answer, DuckDuckGoSearchTool(), VisitWebpageTool(), ShellCommandTool(), CreateFileTool(), ModifyFileTool()],
77
  max_steps=6,
78
  verbosity_level=1,
79
  grammar=None,
requirements.txt CHANGED
@@ -1,5 +1,9 @@
1
- markdownify
2
- smolagents
3
- requests
4
- duckduckgo_search
5
- pandas
 
 
 
 
 
1
+ streamlit>=1.28.0
2
+ requests>=2.31.0
3
+ smolagents>=0.0.2
4
+ langchain>=0.0.312
5
+ pydantic>=2.4.2
6
+ openai>=1.2.0
7
+ gradio>=5.15.0
8
+ pytz>=2023.3
9
+ pyyaml>=6.0
streamlit_app.py ADDED
@@ -0,0 +1,368 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import os
3
+ import sys
4
+ import yaml
5
+ import datetime
6
+ import pytz
7
+ from typing import List, Dict, Any
8
+
9
+ # Ajout du répertoire courant au chemin Python pour importer les modules
10
+ sys.path.append(os.path.dirname(os.path.abspath(__file__)))
11
+
12
+ # Import des composants nécessaires pour l'agent
13
+ from smolagents import CodeAgent
14
+ from smolagents.models import OpenAIServerModel, HfApiModel
15
+ from tools.final_answer import FinalAnswerTool
16
+ from tools.visit_webpage import VisitWebpageTool
17
+ from tools.web_search import DuckDuckGoSearchTool
18
+ from tools.shell_tool import ShellCommandTool
19
+ from tools.create_file_tool import CreateFileTool
20
+ from tools.modify_file_tool import ModifyFileTool
21
+
22
+ # Configuration de la page Streamlit
23
+ st.set_page_config(
24
+ page_title="Agent Conversationnel SmoLAgents 🤖",
25
+ page_icon="🤖",
26
+ layout="wide",
27
+ )
28
+
29
+ def initialize_agent(model_type="openai_server", model_config=None):
30
+ """Initialise l'agent avec les outils et le modèle choisi
31
+
32
+ Args:
33
+ model_type: Type de modèle à utiliser ('openai_server', 'hf_api', etc.)
34
+ model_config: Configuration spécifique au modèle
35
+ """
36
+
37
+ # Configuration du modèle en fonction du type choisi
38
+ if model_type == "openai_server":
39
+ # Configuration par défaut pour OpenAIServerModel
40
+ if model_config is None:
41
+ model_config = {
42
+ "api_base": "http://192.168.1.141:1234/v1",
43
+ "model_id": "Qwen/Qwen2.5-Coder-14B-Instruct-GGUF",
44
+ "api_key": "sk-dummy-key"
45
+ }
46
+
47
+ model = OpenAIServerModel(
48
+ api_base=model_config["api_base"],
49
+ model_id=model_config["model_id"],
50
+ api_key=model_config["api_key"]
51
+ )
52
+
53
+ elif model_type == "hf_api":
54
+ # Configuration par défaut pour HfApiModel
55
+ if model_config is None:
56
+ model_config = {
57
+ "model_id": "http://192.168.1.141:1234/v1",
58
+ "max_new_tokens": 2096,
59
+ "temperature": 0.5
60
+ }
61
+
62
+ model = HfApiModel(
63
+ model_id=model_config["model_id"],
64
+ max_new_tokens=model_config["max_new_tokens"],
65
+ temperature=model_config["temperature"]
66
+ )
67
+
68
+ elif model_type == "hf_cloud":
69
+ # Configuration pour HfApiModel avec un endpoint cloud
70
+ if model_config is None:
71
+ model_config = {
72
+ "model_id": "https://pflgm2locj2t89co.us-east-1.aws.endpoints.huggingface.cloud",
73
+ "max_new_tokens": 2096,
74
+ "temperature": 0.5
75
+ }
76
+
77
+ model = HfApiModel(
78
+ model_id=model_config["model_id"],
79
+ max_new_tokens=model_config["max_new_tokens"],
80
+ temperature=model_config["temperature"]
81
+ )
82
+
83
+ else:
84
+ st.error(f"Type de modèle non supporté: {model_type}")
85
+ return None
86
+
87
+ # Chargement des templates de prompt depuis le fichier YAML
88
+ try:
89
+ with open("prompts.yaml", 'r') as stream:
90
+ prompt_templates = yaml.safe_load(stream)
91
+ except:
92
+ st.error("Impossible de charger prompts.yaml. Utilisation des prompts par défaut.")
93
+ prompt_templates = None
94
+
95
+ # Initialisation des outils
96
+ final_answer = FinalAnswerTool()
97
+
98
+ # Création de l'agent avec les mêmes outils que dans app.py
99
+ agent = CodeAgent(
100
+ model=model,
101
+ tools=[
102
+ final_answer,
103
+ DuckDuckGoSearchTool(),
104
+ VisitWebpageTool(),
105
+ ShellCommandTool(),
106
+ CreateFileTool(),
107
+ ModifyFileTool()
108
+ ],
109
+ max_steps=6,
110
+ verbosity_level=1,
111
+ grammar=None,
112
+ planning_interval=None,
113
+ name=None,
114
+ description=None,
115
+ prompt_templates=prompt_templates
116
+ )
117
+
118
+ return agent
119
+
120
+ def format_step_message(step, is_final=False):
121
+ """Formate les messages de l'agent pour l'affichage dans Streamlit"""
122
+
123
+ if hasattr(step, "model_output") and step.model_output:
124
+ # Nettoyer et formater la sortie du modèle pour l'affichage
125
+ content = step.model_output.strip()
126
+ if not is_final:
127
+ return content
128
+ else:
129
+ return f"**Réponse finale :** {content}"
130
+
131
+ if hasattr(step, "observations") and step.observations:
132
+ # Afficher les observations des outils
133
+ return f"**Observations :** {step.observations.strip()}"
134
+
135
+ if hasattr(step, "error") and step.error:
136
+ # Afficher les erreurs
137
+ return f"**Erreur :** {step.error}"
138
+
139
+ # Cas par défaut
140
+ return str(step)
141
+
142
+ def process_user_input(agent, user_input):
143
+ """Traite l'entrée utilisateur avec l'agent et renvoie les résultats étape par étape"""
144
+
145
+ # Vérification de la connexion au serveur LLM
146
+ try:
147
+ # Exécution de l'agent et capture des étapes
148
+ with st.spinner("L'agent réfléchit..."):
149
+ # Placeholder pour la sortie de l'agent
150
+ response_container = st.container()
151
+
152
+ # Exécution de l'agent et capture des étapes
153
+ steps = []
154
+ final_step = None
155
+
156
+ with response_container:
157
+ step_container = st.empty()
158
+ step_text = ""
159
+
160
+ # Exécute l'agent et capture les étapes de manière incrémentale
161
+ for step in agent.run(user_input, stream=True):
162
+ steps.append(step)
163
+
164
+ # Mettre à jour l'affichage des étapes
165
+ step_number = f"Étape {step.step_number}" if hasattr(step, "step_number") and step.step_number is not None else ""
166
+ step_content = format_step_message(step)
167
+
168
+ # Ajouter au texte des étapes
169
+ if step_number:
170
+ step_text += f"### {step_number}\n\n"
171
+ step_text += f"{step_content}\n\n---\n\n"
172
+
173
+ # Mettre à jour l'affichage
174
+ step_container.markdown(step_text)
175
+
176
+ # Conserver la dernière étape pour la réponse finale
177
+ final_step = step
178
+
179
+ # Afficher la réponse finale
180
+ if final_step:
181
+ final_answer = format_step_message(final_step, is_final=True)
182
+ st.markdown(f"## Réponse Finale\n\n{final_answer}")
183
+
184
+ return final_step
185
+ except Exception as e:
186
+ st.error(f"Erreur lors de l'exécution de l'agent: {str(e)}")
187
+ return None
188
+
189
+ def main():
190
+ st.title("Agent Conversationnel SmoLAgents 🤖")
191
+
192
+ st.markdown("""
193
+ Bienvenue! Cet agent utilise SmoLAgents pour se connecter à un modèle de langage.
194
+ Posez vos questions ci-dessous.
195
+ """)
196
+
197
+ # Sidebar pour la configuration du modèle
198
+ with st.sidebar:
199
+ st.title("Configuration du Modèle")
200
+
201
+ # Sélectionner le type de modèle
202
+ model_type = st.selectbox(
203
+ "Type de modèle",
204
+ ["openai_server", "hf_api", "hf_cloud"],
205
+ index=0,
206
+ help="Choisissez le type de modèle à utiliser avec l'agent"
207
+ )
208
+
209
+ # Configuration spécifique en fonction du type de modèle
210
+ model_config = {}
211
+
212
+ if model_type == "openai_server":
213
+ st.subheader("Configuration OpenAI Server")
214
+ model_config["api_base"] = st.text_input(
215
+ "URL du serveur",
216
+ value="http://192.168.1.141:1234/v1",
217
+ help="Adresse du serveur OpenAI compatible"
218
+ )
219
+ model_config["model_id"] = st.text_input(
220
+ "ID du modèle",
221
+ value="Qwen/Qwen2.5-Coder-14B-Instruct-GGUF",
222
+ help="Identifiant du modèle local"
223
+ )
224
+ model_config["api_key"] = st.text_input(
225
+ "Clé API",
226
+ value="sk-dummy-key",
227
+ type="password",
228
+ help="Clé API pour le serveur (dummy pour LMStudio)"
229
+ )
230
+
231
+ elif model_type == "hf_api":
232
+ st.subheader("Configuration Hugging Face API")
233
+ model_config["model_id"] = st.text_input(
234
+ "URL du modèle",
235
+ value="http://192.168.1.141:1234/v1",
236
+ help="URL du modèle ou endpoint"
237
+ )
238
+ model_config["max_new_tokens"] = st.slider(
239
+ "Tokens maximum",
240
+ min_value=512,
241
+ max_value=4096,
242
+ value=2096,
243
+ help="Nombre maximum de tokens à générer"
244
+ )
245
+ model_config["temperature"] = st.slider(
246
+ "Température",
247
+ min_value=0.1,
248
+ max_value=1.0,
249
+ value=0.5,
250
+ step=0.1,
251
+ help="Température pour la génération (plus élevée = plus créatif)"
252
+ )
253
+
254
+ elif model_type == "hf_cloud":
255
+ st.subheader("Configuration Hugging Face Cloud")
256
+ model_config["model_id"] = st.text_input(
257
+ "URL du endpoint cloud",
258
+ value="https://pflgm2locj2t89co.us-east-1.aws.endpoints.huggingface.cloud",
259
+ help="URL de l'endpoint cloud Hugging Face"
260
+ )
261
+ model_config["max_new_tokens"] = st.slider(
262
+ "Tokens maximum",
263
+ min_value=512,
264
+ max_value=4096,
265
+ value=2096,
266
+ help="Nombre maximum de tokens à générer"
267
+ )
268
+ model_config["temperature"] = st.slider(
269
+ "Température",
270
+ min_value=0.1,
271
+ max_value=1.0,
272
+ value=0.5,
273
+ step=0.1,
274
+ help="Température pour la génération (plus élevée = plus créatif)"
275
+ )
276
+
277
+ # Bouton pour réinitialiser l'agent avec la nouvelle configuration
278
+ if st.button("Appliquer la configuration"):
279
+ with st.spinner("Initialisation de l'agent avec le nouveau modèle..."):
280
+ st.session_state.agent = initialize_agent(model_type, model_config)
281
+ st.success("✅ Configuration appliquée avec succès!")
282
+
283
+ # Vérifier la connexion au serveur
284
+ if model_type == "openai_server":
285
+ llm_api_url = model_config["api_base"].split("/v1")[0]
286
+ try:
287
+ import requests
288
+ response = requests.get(f"{llm_api_url}/health", timeout=2)
289
+ if response.status_code == 200:
290
+ st.success("✅ Connexion au serveur LLM établie")
291
+ else:
292
+ st.warning("⚠️ Le serveur LLM est accessible mais renvoie un statut non-OK")
293
+ except Exception:
294
+ 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.")
295
+
296
+ # Initialisation de l'agent si ce n'est pas déjà fait
297
+ if "agent" not in st.session_state:
298
+ with st.spinner("Initialisation de l'agent..."):
299
+ st.session_state.agent = initialize_agent(model_type, model_config)
300
+
301
+ # Initialisation de l'historique de conversation
302
+ if "messages" not in st.session_state:
303
+ st.session_state.messages = [
304
+ {"role": "assistant", "content": "Bonjour! Comment puis-je vous aider aujourd'hui?"}
305
+ ]
306
+
307
+ # Affichage de l'historique des messages
308
+ for message in st.session_state.messages:
309
+ with st.chat_message(message["role"]):
310
+ st.markdown(message["content"])
311
+
312
+ # Zone de saisie utilisateur
313
+ if prompt := st.chat_input("Posez votre question..."):
314
+ # Ajouter la question de l'utilisateur à l'historique
315
+ st.session_state.messages.append({"role": "user", "content": prompt})
316
+
317
+ # Afficher la question de l'utilisateur
318
+ with st.chat_message("user"):
319
+ st.markdown(prompt)
320
+
321
+ # Traiter la demande avec l'agent
322
+ with st.chat_message("assistant"):
323
+ response = process_user_input(st.session_state.agent, prompt)
324
+
325
+ if response and hasattr(response, "model_output"):
326
+ # Ajouter la réponse à l'historique
327
+ st.session_state.messages.append({"role": "assistant", "content": response.model_output})
328
+
329
+ # Bouton pour effacer l'historique
330
+ if st.sidebar.button("Nouvelle conversation"):
331
+ st.session_state.messages = [
332
+ {"role": "assistant", "content": "Bonjour! Comment puis-je vous aider aujourd'hui?"}
333
+ ]
334
+ st.rerun()
335
+
336
+ # Afficher des informations supplémentaires dans la barre latérale
337
+ with st.sidebar:
338
+ st.title("À propos de cet agent")
339
+ st.markdown("""
340
+ Cet agent utilise SmoLAgents pour se connecter à un modèle de langage hébergé localement.
341
+
342
+ ### Outils disponibles
343
+ - Recherche web (DuckDuckGo)
344
+ - Visite de pages web
345
+ - Exécution de commandes shell
346
+ - Création et modification de fichiers
347
+
348
+ ### Configuration
349
+ Utilisez les options ci-dessus pour configurer le modèle de langage.
350
+
351
+ ### Problèmes courants
352
+ - Si l'agent ne répond pas, vérifiez que le serveur LLM est en cours d'exécution et accessible.
353
+ - Assurez-vous que toutes les dépendances sont installées via `pip install -r requirements.txt`.
354
+ """)
355
+
356
+ # Afficher l'heure actuelle dans différents fuseaux horaires
357
+ st.subheader("Heure actuelle")
358
+ selected_timezone = st.selectbox(
359
+ "Choisissez un fuseau horaire",
360
+ ["Europe/Paris", "America/New_York", "Asia/Tokyo", "Australia/Sydney"]
361
+ )
362
+
363
+ tz = pytz.timezone(selected_timezone)
364
+ local_time = datetime.datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S")
365
+ st.write(f"L'heure actuelle à {selected_timezone} est: {local_time}")
366
+
367
+ if __name__ == "__main__":
368
+ main()
tools/create_file_tool.py ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Any, Optional
2
+ from smolagents.tools import Tool
3
+ import os
4
+ import sys
5
+
6
+ class CreateFileTool(Tool):
7
+ name = "create_file"
8
+ description = "Creates a new file with the specified content."
9
+ inputs = {
10
+ 'path': {'type': 'string', 'description': 'The path of the file to create.'},
11
+ 'content': {'type': 'string', 'description': 'The content to write in the file.'}
12
+ }
13
+ output_type = "string"
14
+
15
+ def __init__(self, **kwargs):
16
+ super().__init__()
17
+ # Detect the operating system
18
+ self.is_windows = sys.platform.startswith('win')
19
+
20
+ def forward(self, path: str, content: str) -> str:
21
+ try:
22
+ # Ensure the parent directory exists
23
+ directory = os.path.dirname(path)
24
+ if directory and not os.path.exists(directory):
25
+ os.makedirs(directory)
26
+
27
+ # Write the content to the file
28
+ with open(path, 'w', encoding='utf-8') as file:
29
+ file.write(content)
30
+
31
+ return f"File created successfully: {path}"
32
+ except Exception as e:
33
+ return f"Error while creating the file: {str(e)}"
tools/modify_file_tool.py ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Any, Optional
2
+ from smolagents.tools import Tool
3
+ import os
4
+ import sys
5
+
6
+ class ModifyFileTool(Tool):
7
+ name = "modify_file"
8
+ description = "Modify an existing file."
9
+ inputs = {
10
+ 'path': {'type': 'string', 'description': 'The path of the file to modify.'},
11
+ 'content': {'type': 'string', 'description': 'The new content of the file.'},
12
+ 'append': {'type': 'boolean', 'description': 'If true, append the content to the end of the file instead of replacing it.', 'nullable': True}
13
+ }
14
+ output_type = "string"
15
+
16
+ def __init__(self, **kwargs):
17
+ super().__init__()
18
+ # Detect the operating system
19
+ self.is_windows = sys.platform.startswith('win')
20
+
21
+ def forward(self, path: str, content: str, append: bool = False) -> str:
22
+ try:
23
+ # Check if the file exists
24
+ if not os.path.exists(path):
25
+ return f"Error: The file {path} does not exist."
26
+
27
+ # Open mode based on the append option
28
+ mode = 'a' if append else 'w'
29
+
30
+ # Modify the file
31
+ with open(path, mode, encoding='utf-8') as file:
32
+ file.write(content)
33
+
34
+ action = "modified" if not append else "updated (content added)"
35
+ return f"File {action} successfully: {path}"
36
+ except Exception as e:
37
+ return f"Error while modifying the file: {str(e)}"
tools/shell_tool.py ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Any, Optional
2
+ from smolagents.tools import Tool
3
+ import duckduckgo_search
4
+ import subprocess
5
+ import sys
6
+
7
+ class ShellCommandTool(Tool):
8
+ name = "shell_command"
9
+ description = "Executes a shell command and returns the result."
10
+ inputs = {'command': {'type': 'string', 'description': 'The shell command to execute.'}}
11
+ output_type = "string"
12
+
13
+ def __init__(self, timeout=60, **kwargs):
14
+ super().__init__()
15
+ self.timeout = timeout
16
+ # Detect the operating system
17
+ self.is_windows = sys.platform.startswith('win')
18
+
19
+ def forward(self, command: str) -> str:
20
+ try:
21
+ # Use shell=True for complex commands
22
+ # Use different configurations based on the OS
23
+ if self.is_windows:
24
+ process = subprocess.run(
25
+ command,
26
+ capture_output=True,
27
+ text=True,
28
+ shell=True,
29
+ timeout=self.timeout,
30
+ executable="cmd.exe" if self.is_windows else None
31
+ )
32
+ else:
33
+ process = subprocess.run(
34
+ command,
35
+ capture_output=True,
36
+ text=True,
37
+ shell=True,
38
+ timeout=self.timeout
39
+ )
40
+
41
+ # Return stdout and stderr if present
42
+ result = ""
43
+ if process.stdout:
44
+ result += f"## Standard Output\n```\n{process.stdout}\n```\n\n"
45
+ if process.stderr:
46
+ result += f"## Standard Error\n```\n{process.stderr}\n```\n\n"
47
+
48
+ result += f"Exit Code: {process.returncode}"
49
+ return result
50
+
51
+ except subprocess.TimeoutExpired:
52
+ return "The command has timed out."
53
+ except Exception as e:
54
+ return f"Error while executing the command: {str(e)}"
tools/visit_webpage.py CHANGED
@@ -3,6 +3,7 @@ from smolagents.tools import Tool
3
  import requests
4
  import markdownify
5
  import smolagents
 
6
 
7
  class VisitWebpageTool(Tool):
8
  name = "visit_webpage"
 
3
  import requests
4
  import markdownify
5
  import smolagents
6
+ import re
7
 
8
  class VisitWebpageTool(Tool):
9
  name = "visit_webpage"
toto.py ADDED
@@ -0,0 +1 @@
 
 
1
+ # This is a newly created Python file named toto.py