mokrane25 commited on
Commit
c9ed76f
·
verified ·
1 Parent(s): 1f848f3

Update README.md

Browse files
Files changed (1) hide show
  1. README.md +322 -0
README.md CHANGED
@@ -10,5 +10,327 @@ pinned: false
10
  license: mit
11
  short_description: GALITA is a self-evolving generalist AI agent
12
  ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
 
14
  An example chatbot using [Gradio](https://gradio.app), [`huggingface_hub`](https://huggingface.co/docs/huggingface_hub/v0.22.2/en/index), and the [Hugging Face Inference API](https://huggingface.co/docs/api-inference/index).
 
10
  license: mit
11
  short_description: GALITA is a self-evolving generalist AI agent
12
  ---
13
+ Made by:
14
+ Mohammed Dahbani
15
+ Anas Ezzakri
16
+ Adam Lagssaibi
17
+ Mouhcine Zahdi
18
+ Mahmoud Mokrane
19
+
20
+ # Gradio-hackathon : Generalist self-evolving ai agent inspired by Alita
21
+ This is my team project for the gradio hackathon 2025
22
+ This Project is inspired by research paper : `https://arxiv.org/abs/2505.20286`
23
+
24
+ # 📁 Structure du projet
25
+ ```bash
26
+ alita_agent/
27
+
28
+ ├── main.py # Point d'entrée principal : exécute un TaskPrompt via le ManagerAgent
29
+ ├── manager_agent.py # Logique de coordination centrale, il orchestre tous les composants
30
+ ├── task_prompt.py # Définit la classe TaskPrompt, contenant la requête utilisateur initiale
31
+
32
+ ├── components/ # Contient tous les composants fonctionnels modulaires
33
+ │ ├── __init__.py # Rends le dossier importable comme un package
34
+ │ ├── script_generator.py # Génère dynamiquement du code Python à partir d'un MCPToolSpec
35
+ │ ├── code_runner.py # Exécute un script dans un environnement isolé et capture le résultat
36
+ │ ├── mcp_registry.py # Gère l'enregistrement, la recherche et la réutilisation des outils MCP
37
+ │ ├── web_agent.py # Effectue des recherches web ou GitHub pour aider à la génération de code
38
+ │ └── mcp_brainstormer.py # Génère des MCPToolSpec en analysant la tâche utilisateur
39
+
40
+ ├── models/ # Contient les classes de données (dataclasses) utilisées dans tout le système
41
+ │ ├── __init__.py # Rends le dossier importable comme un package
42
+ │ ├── mcp_tool_spec.py # Définition de MCPToolSpec (dataclass) : nom, schémas I/O, description, pseudo-code, etc.
43
+ │ └── mcp_execution_result.py # Définition de MCPExecutionResult (dataclass) : succès, sortie, logs, erreur
44
+
45
+ ├── tests/ # Contient les tests unitaires pour chaque module
46
+ │ ├── __init__.py # Rends le dossier importable comme un package
47
+ │ ├── test_script_generator.py # Tests pour vérifier la génération correcte de code et d'environnements
48
+ │ ├── test_code_runner.py # Tests pour s'assurer de la bonne exécution des scripts et gestion d'erreurs
49
+ │ ├── test_mcp_registry.py # Tests de l'enregistrement, recherche et appel d'outils dans le registre MCP
50
+ │ └── test_manager_agent.py # Tests d'intégration sur le comportement global du ManagerAgent
51
+
52
+ └── README.md # Documentation du projet, instructions, pipeline, inspirations et lien vers le papier
53
+ ```
54
+
55
+ # Project Pipeline
56
+
57
+ #### 🔄 Le flux complet avec vérification de l'existence
58
+ 1. L'utilisateur envoie un TaskPrompt
59
+ 2. Le Manager Agent demande au MCPBrainstormer : "Quels outils faudrait-il pour résoudre cette tâche ?"
60
+ 3. Le Brainstormer propose une ou plusieurs specs (MCPToolSpec)
61
+ 4. Le Manager Agent consulte le MCPRegistry : "Ai-je déjà un outil enregistré dont le nom + I/O matchent cette spec ?"
62
+ - Oui ? ➜ réutilise l'outil existant
63
+ - Non ? ➜ il appel le web agent pour une recherche d'outils open-source pour implementer. Puis, le Manager prend la recherche et la donne a Brainstormer pour commencer la construction.
64
+
65
+ #### 🔍 Comment détecter que l'outil existe déjà ?
66
+ Par matching sur la spec MCPToolSpec :
67
+ - Nom exact (ou identifiant unique comme un hash)
68
+
69
+ - Ou plus intelligemment :
70
+ - même structure input_schema
71
+ - même output_schema
72
+ - mêmes rôles ou description proche (avec embedding / vector search)
73
+
74
+ ```python
75
+ def check_existing_tool(spec: MCPToolSpec, registry: MCPRegistry) -> Optional[str]:
76
+ for registered_spec in registry.list_tools():
77
+ if registered_spec.input_schema == spec.input_schema and \
78
+ registered_spec.output_schema == spec.output_schema:
79
+ return registry.get_tool_endpoint(registered_spec.name)
80
+ return None
81
+ ```
82
+
83
+ #### 💬 Que fait l'agent s'il le trouve ?
84
+ Il ne régénère rien :
85
+ - Il ajoute l'appel de l'outil MCP existant dans son plan
86
+ - Il formate l'entrée JSON
87
+ - Il appelle POST /predict directement
88
+ - Il utilise la réponse dans la suite de son raisonnement
89
+
90
+ #### 💡 Cas pratiques
91
+ Differents cas et Réaction attendue de l'agent
92
+
93
+ | Situation réelle | Réaction de l'agent |
94
+ | ----------------------------------------- | ------------------------------------------------------------------------ |
95
+ | L'outil `"SubtitleExtractor"` existe déjà | L'agent appelle directement l'endpoint |
96
+ | Le spec est proche mais pas identique | L'agent peut quand même le réutiliser (avec adaptation) |
97
+ | L'outil existe mais a échoué | L'agent peut **fallback** vers génération d'un nouvel outil MCP |
98
+ | L'outil existe mais est obsolète | Le Registry peut signaler une mise à jour ou déclencher une régénération |
99
+
100
+
101
+ #### Fonctions attendues
102
+
103
+ | Classe | Méthode attendue | Présente ? | Commentaire |
104
+ | -------------------- | ------------------------------------------ | ---------- | ----------- |
105
+ | `ManagerAgent` | `run_task(prompt)` | ✅ | OK |
106
+ | `MCPBrainstormer` | `brainstorm(prompt)` | ✅ | OK |
107
+ | `WebAgent` | `search_github`, `retrieve_readme` | ✅ | OK |
108
+ | `ScriptGenerator` | `generate_code`, `generate_env_script` | ✅ | OK |
109
+ | `CodeRunner` | `execute`, `setup_environment` | ✅ | OK |
110
+ | `MCPRegistry` | `register_tool`, `list_tools`, `call_tool` | ✅ | OK |
111
+ | `MCPExecutionResult` | attributs `success`, `output`, `logs` | ✅ | OK |
112
+ | `MCPToolSpec` | `name`, `input_schema`, etc. | ✅ | OK |
113
+
114
+ Ici Le ManagerAgent coordonne tout. Il délègue à :
115
+ - MCPBrainstormer → pour générer des specs d'outils.
116
+ - ScriptGenerator → pour générer du code.
117
+ - CodeRunner → pour tester le code.
118
+ - WebAgent → pour récupérer du contexte externe.
119
+ - MCPRegistry → pour enregistrer et réutiliser les outils.
120
+
121
+
122
+ ![](alitaDiagram.svg)
123
+
124
+
125
+ ```sh
126
+ plantuml -tsvg README.md
127
+ ```
128
+
129
+ <div hidden>
130
+ <details>
131
+ <summary>Voir le script PlantUML</summary>
132
+ ```plantuml
133
+ @startuml alitaDiagram
134
+
135
+ skinparam classAttributeIconSize 0
136
+
137
+ ' === Classes de données ===
138
+ class TaskPrompt {
139
+ - text: str
140
+ }
141
+
142
+ class MCPToolSpec {
143
+ - name: str
144
+ - input_schema: dict
145
+ - output_schema: dict
146
+ - description: str
147
+ - pseudo_code: str
148
+ - source_hint: str
149
+ }
150
+
151
+ class MCPExecutionResult {
152
+ - success: bool
153
+ - output: dict
154
+ - logs: str
155
+ - error_message: str
156
+ }
157
+
158
+ class ToolCall {
159
+ - tool_name: str
160
+ - input_data: dict
161
+ - result: dict
162
+ }
163
+
164
+
165
+ ' === Agents principaux ===
166
+ class ManagerAgent {
167
+ - brainstormer: MCPBrainstormer
168
+ - web_agent: WebAgent
169
+ - generator: ScriptGenerator
170
+ - runner: CodeRunner
171
+ - registry: MCPRegistry
172
+ + run_task(prompt: TaskPrompt): dict
173
+ + check_existing_tool(spec: MCPToolSpec) -> Optional[str]
174
+ }
175
+
176
+ class MCPBrainstormer {
177
+ + brainstorm(prompt: TaskPrompt): List<MCPToolSpec>
178
+ }
179
+
180
+ class WebAgent {
181
+ + search_github(query: str): str
182
+ + retrieve_readme(repo_url: str): str
183
+ }
184
+
185
+ class ScriptGenerator {
186
+ + generate_code(spec: MCPToolSpec): str
187
+ + generate_env_script(spec: MCPToolSpec): str
188
+ }
189
+
190
+ class CodeRunner {
191
+ + execute(script: str): MCPExecutionResult
192
+ + setup_environment(env_script: str): bool
193
+ }
194
+
195
+ class MCPRegistry {
196
+ + register_tool(spec: MCPToolSpec, endpoint_url: str): void
197
+ + list_tools(): List<MCPToolSpec>
198
+ + call_tool(tool: str): object
199
+ }
200
+
201
+
202
+
203
+ ' === Relations avec types + cardinalités ===
204
+
205
+ ' Le Manager reçoit une tâche utilisateur
206
+ TaskPrompt --> "1" ManagerAgent : provides query
207
+
208
+ ' Manager appelle le Brainstormer
209
+ ManagerAgent --> "1" MCPBrainstormer : calls
210
+
211
+ ' Manager utilise WebAgent
212
+ ManagerAgent "1" <--> "1" WebAgent : queries/answers
213
+
214
+ ' Brainstormer appelle ScriptGenerator et CodeRunner
215
+ MCPBrainstormer --> "1" ScriptGenerator : plans
216
+ MCPBrainstormer --> "1" CodeRunner : validates
217
+
218
+ ' Manager consulte ou enregistre dans le Registry
219
+ ManagerAgent --> "1" MCPRegistry : checks/updates
220
+
221
+ ' Manager construit un plan d'appel d'outils
222
+ ManagerAgent --> "0..*" ToolCall : creates
223
+
224
+ ' Brainstormer retourne des MCPToolSpec
225
+ MCPBrainstormer --> "1..*" MCPToolSpec : returns
226
+
227
+ ' ScriptGenerator utilise MCPToolSpec pour générer
228
+ ScriptGenerator --> "1" MCPToolSpec : consumes
229
+
230
+ ' Registry enregistre des ToolSpecs
231
+ MCPRegistry --> "0..*" MCPToolSpec : stores
232
+
233
+ ' CodeRunner renvoie un résultat d'exécution
234
+ CodeRunner --> "1" MCPExecutionResult : returns
235
+
236
+ ' CodeRunner peut utiliser des outils enregistrés
237
+ CodeRunner --> "0..*" MCPRegistry : queries
238
+
239
+
240
+ @enduml
241
+ ```
242
+ </details>
243
+ </div>
244
+
245
+ # ALITA Research Functionality
246
+
247
+ This README explains how to use the comprehensive research capabilities of the ALITA ManagerAgent.
248
+
249
+ ## Overview
250
+
251
+ ALITA can now perform deep, autonomous web research using the WebAgent's research functionality. This allows ALITA to gather information from multiple sources, analyze it, and synthesize a comprehensive report on any topic.
252
+
253
+ ## Usage Methods
254
+
255
+ There are two ways to use the research functionality:
256
+
257
+ ### 1. Direct Research Method
258
+
259
+ Call the `research` method directly on the ManagerAgent instance:
260
+
261
+ ```python
262
+ from manager_agent import ManagerAgent
263
+ from llama_index.llms.anthropic import Anthropic
264
+
265
+ # Initialize the LLM and ManagerAgent
266
+ llm = Anthropic(model="claude-3-5-sonnet-20241022", api_key="your-api-key")
267
+ manager = ManagerAgent(llm=llm)
268
+
269
+ # Perform research directly
270
+ report = manager.research(
271
+ query="What are the latest developments in quantum computing?",
272
+ max_iterations=50, # Optional: limit the number of research steps
273
+ verbose=True # Optional: show detailed progress
274
+ )
275
+
276
+ # The report variable now contains a comprehensive research report
277
+ print(report)
278
+ ```
279
+
280
+ ### 2. Tool-Based Research through ReActAgent
281
+
282
+ Let the ManagerAgent's internal ReActAgent decide when to use research:
283
+
284
+ ```python
285
+ from manager_agent import ManagerAgent
286
+ from models import TaskPrompt
287
+ from llama_index.llms.anthropic import Anthropic
288
+
289
+ # Initialize the LLM and ManagerAgent
290
+ llm = Anthropic(model="claude-3-5-sonnet-20241022", api_key="your-api-key")
291
+ manager = ManagerAgent(llm=llm)
292
+
293
+ # Create a task prompt
294
+ task_prompt = TaskPrompt(text="I need a comprehensive report on recent developments in quantum computing.")
295
+
296
+ # Run the task through the agent
297
+ response = manager.run_task(task_prompt)
298
+
299
+ # The response will include the research report if the agent determined research was needed
300
+ print(response)
301
+ ```
302
+
303
+ The agent will automatically detect when deep research is required based on keywords like "comprehensive," "thorough," "research," etc.
304
+
305
+ ## Running the Test Script
306
+
307
+ A test script is provided to demonstrate both usage methods:
308
+
309
+ ```bash
310
+ python test_research.py
311
+ ```
312
+
313
+ Make sure to set your Anthropic API key in the environment or in a `.env` file before running the script.
314
+
315
+ ## System Prompt Configuration
316
+
317
+ The ManagerAgent's system prompt has been updated to include guidance on when to use the research tool:
318
+
319
+ - For simple information needs: use 'web_search' for quick answers
320
+ - For complex research topics: use 'perform_web_research' for comprehensive autonomous research
321
+
322
+ ## How Research Works
323
+
324
+ When ALITA performs research:
325
+
326
+ 1. It first analyzes the research query to understand what information is needed
327
+ 2. It uses web search to gather relevant sources
328
+ 3. It visits and reads the content of each source
329
+ 4. It downloads and analyzes relevant documents if needed
330
+ 5. It evaluates the credibility and relevance of each source
331
+ 6. It synthesizes the information into a comprehensive report
332
+ 7. It includes citations and references to the sources used
333
+
334
+ This enables ALITA to provide high-quality, well-researched answers to complex questions.
335
 
336
  An example chatbot using [Gradio](https://gradio.app), [`huggingface_hub`](https://huggingface.co/docs/huggingface_hub/v0.22.2/en/index), and the [Hugging Face Inference API](https://huggingface.co/docs/api-inference/index).