goblin-agents 0.1.10 → 0.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +146 -116
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -4,6 +4,15 @@
4
4
 
5
5
  Le module `goblin-agents` fournit une infrastructure complète pour intégrer des agents d'intelligence artificielle (IA) dans l'écosystème Xcraft. Il permet de créer, configurer et interagir avec différents modèles de langage (LLM) via des fournisseurs comme Ollama et OpenAI. Ce module est conçu pour faciliter l'utilisation d'agents IA dans diverses applications, en offrant des fonctionnalités avancées comme la gestion de conversations, l'analyse de documents PDF, et l'utilisation d'outils externes.
6
6
 
7
+ ## Sommaire
8
+
9
+ - [Structure du module](#structure-du-module)
10
+ - [Fonctionnement global](#fonctionnement-global)
11
+ - [Exemples d'utilisation](#exemples-dutilisation)
12
+ - [Interactions avec d'autres modules](#interactions-avec-dautres-modules)
13
+ - [Configuration avancée](#configuration-avancée)
14
+ - [Détails des sources](#détails-des-sources)
15
+
7
16
  ## Structure du module
8
17
 
9
18
  - **AiAgent** : Acteur principal qui encapsule un agent IA et ses fonctionnalités
@@ -41,7 +50,7 @@ async initAgents() {
41
50
  const feedId = await this.newQuestFeed();
42
51
 
43
52
  // Création d'un agent avec Ollama (local)
44
- const ollamaAgentId = SmartId.from('aiAgent', 'ollama-mistral-assistant');
53
+ const ollamaAgentId = 'aiAgent@ollama-mistral-assistant';
45
54
  const agent = await new AiAgent(this).create(ollamaAgentId, feedId, {
46
55
  name: 'Assistant Personnel',
47
56
  role: 'assistant',
@@ -56,8 +65,8 @@ async initAgents() {
56
65
  });
57
66
 
58
67
  // Création d'un agent avec OpenAI (cloud)
59
- const openAiAgentId = SmartId.from('aiAgent', 'gpt-4o-assistant');
60
- const agent = await new AiAgent(this).create(openAiAgentId, feedId, {
68
+ const openAiAgentId = 'aiAgent@gpt-4o-assistant';
69
+ const cloudAgent = await new AiAgent(this).create(openAiAgentId, feedId, {
61
70
  name: 'Assistant Personnel',
62
71
  role: 'assistant',
63
72
  provider: 'open-ai',
@@ -68,6 +77,7 @@ async initAgents() {
68
77
  },
69
78
  usability: 'stable'
70
79
  });
80
+ }
71
81
  ```
72
82
 
73
83
  ### Conversation avec un agent
@@ -92,31 +102,6 @@ async askAgent(desktopId, agentId, contextId, question, saveExchange = false) {
92
102
  }
93
103
  ```
94
104
 
95
- ### Résumer et "squasher" un contexte
96
-
97
- ```javascript
98
- // Dans une méthode d'un acteur Elf
99
- async resumeAndSquashContexte(agentId, contextId) {
100
- const feedId = await this.newQuestFeed();
101
-
102
- // Instancie l'agent approprié par ex. 'aiAgent@gpt-4o-assistant'
103
- const agent = await new AiAgent(this).create(agentId, feedId);
104
-
105
- // Demande un résumé des échanges
106
- const resumePrompt = "Résume l'essentiel de nos échanges en utilisant l'historique des messages";
107
- const resumedContent = await agent.resumeExchange(resumePrompt, contextId);
108
-
109
- // Reset la mémoire contextuel et persiste le changement
110
- await agent.reset(contextId, true);
111
-
112
- // Ajoute un nouvel historique d'échange a partir du résumé
113
- await agent.set(contextId, [{role: 'assistant', content: resumedContent}]);
114
-
115
- // Sauve ce nouvel état
116
- await agent.save();
117
- }
118
- ```
119
-
120
105
  ### Utilisation d'outils externes
121
106
 
122
107
  ```javascript
@@ -152,23 +137,17 @@ async addWeatherToolSupportToAgent(agentId) {
152
137
  }
153
138
  ]
154
139
  });
155
- }
156
140
 
157
-
158
- // L'agent pourra maintenant utiliser l'outil weather.getWeather
159
- const question = "Quel temps fait-il à Paris aujourd'hui?";
160
- const response = await agent.chat(contextId, question, desktopId);
141
+ // L'agent pourra maintenant utiliser l'outil weather.getWeather
142
+ const question = "Quel temps fait-il à Paris aujourd'hui?";
143
+ const response = await agent.chat(contextId, question, desktopId);
144
+ }
161
145
  ```
162
146
 
163
147
  ### Génération d'embeddings pour la recherche sémantique
164
148
 
165
149
  ```javascript
166
150
  // Dans une méthode d'un acteur Elf
167
- // {
168
- // 'indexContent@article-1', 'Contenu à indexer'
169
- // 'indexContent@article-2', 'Un autre contenu à indexer'
170
- // }
171
- //
172
151
  async updateKnowledgeBase(articles) {
173
152
  const feedId = await this.newQuestFeed();
174
153
 
@@ -212,36 +191,6 @@ async updateKnowledgeBase(articles) {
212
191
  );
213
192
  }
214
193
  }
215
-
216
- // Dans une méthode d'un acteur Elf
217
- async queryKnowledgeBase(question = "Comment fonctionne l'apprentissage par renforcement?") {
218
- const feedId = await this.newQuestFeed();
219
-
220
- // Instancie l'agent approprié pour faire un embedding
221
- // par ex. 'aiAgent@default-embedder'
222
- const agent = await new AiAgent(this).create(agentId, feedId);
223
-
224
- // Générer un embedding pour un texte, par ex. pour une recherche
225
- // Convertit la question texte en vecteurs
226
- const vectors = await agent.embed(question);
227
-
228
- // Effectue une recherche par similitude dans cryo
229
- // Utilise un Archetype "IndexedContent"
230
- // Limite la recherche au contenu indexé en français
231
- // avec un scope 'knowledge-base'
232
- // les 100 premier résultats les plus pertinents
233
- const results = await this.cryo.searchDistance2(
234
- IndexedContentLogic.db,
235
- vectors,
236
- ['fr'],
237
- ['knowledge-base'],
238
- 100
239
- );
240
-
241
- // Itère sur les données et retourne les résultats
242
- // a l'appelant
243
- return Array.from(results);
244
- }
245
194
  ```
246
195
 
247
196
  ## Interactions avec d'autres modules
@@ -251,24 +200,25 @@ Le module `goblin-agents` interagit avec plusieurs autres composants de l'écosy
251
200
  - **[xcraft-core-goblin]** : Fournit l'infrastructure Elf pour la création d'acteurs
252
201
  - **[xcraft-core-stones]** : Utilisé pour la définition des types de données
253
202
  - **[xcraft-core-utils]** : Utilisé pour les appels API REST et la gestion des verrous
203
+ - **[xcraft-core-etc]** : Utilisé pour la gestion de la configuration du module
254
204
 
255
205
  Le module peut également interagir avec d'autres services Goblin via le système d'appels d'outils, permettant aux agents d'effectuer des actions concrètes dans l'application.
256
206
 
257
207
  ## Configuration avancée
258
208
 
259
- | Option | Description | Type | Valeur par défaut |
260
- |--------|-------------|------|------------------|
261
- | version | Version des agents | Number | 2 |
262
- | defaultProfile | Profil par défaut des agents | String | null |
263
- | defaultSettings | Paramètres par défaut | Object | null |
264
- | profiles | Profils pour remplacer les paramètres | Object | {} |
265
- | settings | Paramètres par nom | Object | {} |
209
+ | Option | Description | Type | Valeur par défaut |
210
+ | --------------- | ------------------------------------- | ------ | ----------------- |
211
+ | version | Version des agents | Number | 2 |
212
+ | defaultProfile | Profil par défaut des agents | String | null |
213
+ | defaultSettings | Paramètres par défaut | Object | null |
214
+ | profiles | Profils pour remplacer les paramètres | Object | {} |
215
+ | settings | Paramètres par nom | Object | {} |
266
216
 
267
217
  ## Détails des sources
268
218
 
269
219
  ### `aiAgent.js`
270
220
 
271
- Ce fichier est le point d'entrée du module, exportant les commandes Xcraft pour l'acteur AiAgent. Il importe l'acteur et sa logique depuis le fichier principal et les expose au système Xcraft.
221
+ Ce fichier est le point d'entrée du module, exportant les commandes Xcraft pour l'acteur AiAgent. Il importe l'acteur et sa logique depuis le fichier principal et les expose au système Xcraft via `Elf.birth()`.
272
222
 
273
223
  ### `config.js`
274
224
 
@@ -307,67 +257,147 @@ L'état d'un agent IA est défini par la classe `AiAgentShape` qui contient les
307
257
  - `host` : URL du serveur LLM
308
258
  - `headers` : En-têtes HTTP pour les requêtes API
309
259
  - `messages` : Historique des messages par contexte
310
- - `options` : Options de configuration du modèle
260
+ - `options` : Options de configuration du modèle (voir OptionsShape)
311
261
  - `format` : Format de sortie attendu
312
262
  - `tools` : Outils externes disponibles pour l'agent
313
263
  - `toolServiceId` : Identifiant du service d'outils
314
264
  - `usability` : État d'utilisabilité ('disabled', 'experimental', 'stable', 'deprecated')
315
265
  - `meta` : Métadonnées de l'agent
316
266
 
267
+ La classe `OptionsShape` définit de nombreuses options de configuration pour les modèles LLM, incluant des paramètres comme la température, la taille du contexte, les pénalités de répétition, et les options d'optimisation mémoire.
268
+
269
+ #### Cycle de vie de l'acteur
270
+
271
+ L'acteur AiAgent suit le cycle de vie standard des acteurs Elf Archetype :
272
+
273
+ 1. **Création** : Via la méthode `create()` qui initialise l'agent avec un ID et un état
274
+ 2. **Configuration** : Via `patch()` pour modifier les paramètres ou `upgrade()` pour les mises à jour de version
275
+ 3. **Utilisation** : Via les méthodes de conversation et de génération
276
+ 4. **Persistance** : Via `save()` pour sauvegarder l'état
277
+ 5. **Suppression** : Via `trash()` pour marquer comme supprimé ou `delete()` pour suppression définitive
278
+
317
279
  #### Méthodes publiques
318
280
 
319
- - **`create(id, desktopId, agentState)`** - Crée un nouvel agent avec l'ID et l'état spécifiés.
320
- - **`patch(agentState)`** - Met à jour l'état de l'agent avec les propriétés fournies.
321
- - **`upgrade(version, agentState)`** - Met à niveau l'agent vers une nouvelle version avec l'état spécifié.
322
- - **`gen(prompt)`** - Génère du texte à partir d'un prompt.
323
- - **`reset(contextId, save)`** - Réinitialise l'historique des messages pour un contexte spécifique.
324
- - **`readPDFpages(pdfPath)`** - Extrait le texte des pages d'un document PDF.
325
- - **`embed(rawText)`** - Génère un embedding vectoriel pour un texte donné.
326
- - **`embedInBatch(rawTexts)`** - Génère des embeddings vectoriels pour plusieurs textes en une seule requête.
327
- - **`set(contextId, messages)`** - Définit l'historique des messages pour un contexte spécifique.
328
- - **`chat(contextId, question, userDesktopId, sessionId)`** - Engage une conversation avec l'agent dans un contexte spécifique.
329
- - **`callTools(contextId, message, userDesktopId, sessionId)`** - Appelle des outils externes en fonction des demandes de l'agent.
330
- - **`addToolMessage(contextId, toolId, toolName, answer)`** - Ajoute une réponse d'outil à l'historique des messages.
331
- - **`ask(contextId, question, questionId)`** - Pose une question à l'agent avec streaming de la réponse.
332
- - **`resumeExchange(resumePrompt, contextId)`** - Résume un échange de conversation.
333
- - **`react(reactPrompt, contextId, question)`** - Utilise le paradigme ReAct pour raisonner et agir sur une question.
334
- - **`callAgent(contextId, agentId, action, feedId)`** - Appelle un autre agent pour effectuer une action.
335
- - **`addAssistantMessage(contextId, message)`** - Ajoute un message de l'assistant à l'historique.
336
- - **`save()`** - Persiste l'état de l'agent.
337
- - **`change(path, newValue)`** - Modifie une propriété spécifique de l'état de l'agent.
338
- - **`getUserChatContextHistory(contextId, filterTool)`** - Récupère l'historique des messages pour un contexte spécifique.
339
- - **`getBaseSettings()`** - Récupère les paramètres de base de l'agent.
340
- - **`getUsability()`** - Récupère l'état d'utilisabilité de l'agent.
341
- - **`trash()`** - Marque l'agent comme supprimé.
342
- - **`delete()`** - Supprime l'agent.
281
+ **`create(id, desktopId, agentState)`** - Crée un nouvel agent avec l'ID et l'état spécifiés. Persiste automatiquement l'agent après création.
282
+
283
+ **`patch(agentState)`** - Met à jour l'état de l'agent avec les propriétés fournies et persiste les changements.
284
+
285
+ **`upgrade(version, agentState)`** - Met à niveau l'agent vers une nouvelle version avec l'état spécifié, uniquement si la version est supérieure à la version actuelle.
286
+
287
+ **`gen(prompt)`** - Génère du texte à partir d'un prompt en utilisant le modèle configuré de l'agent.
288
+
289
+ **`reset(contextId, save)`** - Réinitialise l'historique des messages pour un contexte spécifique. Si aucun contextId n'est fourni, réinitialise tous les contextes.
290
+
291
+ **`readPDFpages(pdfPath)`** - Extrait le texte des pages d'un document PDF en utilisant l'OCR via un modèle multimodal.
292
+
293
+ **`embed(rawText)`** - Génère un embedding vectoriel pour un texte donné, retourné sous forme de littéral SQL hexadécimal.
294
+
295
+ **`embedInBatch(rawTexts)`** - Génère des embeddings vectoriels pour plusieurs textes en une seule requête, optimisé pour les traitements par lots.
296
+
297
+ **`set(contextId, messages)`** - Définit directement l'historique des messages pour un contexte spécifique.
298
+
299
+ **`chat(contextId, question, userDesktopId, sessionId)`** - Engage une conversation avec l'agent dans un contexte spécifique. Gère automatiquement l'historique et les appels d'outils.
300
+
301
+ **`ask(contextId, question, questionId)`** - Pose une question à l'agent avec streaming de la réponse (uniquement pour Ollama). Émet des événements pour chaque partie de la réponse.
302
+
303
+ **`resumeExchange(resumePrompt, contextId)`** - Reprend un échange existant avec un nouveau prompt système, en utilisant l'historique du contexte comme base.
304
+
305
+ **`react(reactPrompt, contextId, question)`** - Utilise le paradigme ReAct (Reasoning and Acting) pour permettre à l'agent de raisonner et d'agir de manière autonome.
306
+
307
+ **`callAgent(contextId, agentId, action, feedId)`** - Appelle un autre agent pour effectuer une action spécifique dans le cadre d'une orchestration multi-agents.
308
+
309
+ **`addAssistantMessage(contextId, message)`** - Ajoute un message de l'assistant à l'historique d'un contexte spécifique.
310
+
311
+ **`change(path, newValue)`** - Modifie une propriété spécifique de l'état de l'agent avec gestion automatique des types pour certains paramètres.
312
+
313
+ **`getUserChatContextHistory(contextId, filterTool)`** - Récupère l'historique des messages pour un contexte spécifique avec option de filtrage des messages d'outils.
314
+
315
+ **`getBaseSettings()`** - Retourne les paramètres de base de l'agent (provider, host, headers, model).
316
+
317
+ **`getUsability()`** - Retourne l'état d'utilisabilité de l'agent.
318
+
319
+ **`trash()`** - Marque l'agent comme supprimé en changeant son statut meta à 'trashed'.
320
+
321
+ **`save()`** - Persiste l'état actuel de l'agent sur le disque.
343
322
 
344
323
  ### `lib/llm/providers.js`
345
324
 
346
- Ce fichier définit les classes pour interagir avec différents fournisseurs de LLM :
325
+ Ce fichier définit l'architecture des fournisseurs de LLM avec une classe abstraite `LLMProvider` et ses implémentations concrètes :
326
+
327
+ #### LLMProvider (classe abstraite)
328
+
329
+ Définit l'interface commune que tous les fournisseurs doivent implémenter :
330
+
331
+ - `chat()` : Conversation avec le modèle
332
+ - `gen()` : Génération de texte
333
+ - `embed()` : Génération d'embeddings
334
+ - `embedInBatch()` : Génération d'embeddings par lots
335
+
336
+ #### OllamaProvider
337
+
338
+ Implémentation pour le fournisseur Ollama (serveur local) :
347
339
 
348
- - **LLMProvider** : Classe abstraite définissant l'interface commune
349
- - **OllamaProvider** : Implémentation pour le fournisseur Ollama (local)
350
- - **OpenAIProvider** : Implémentation pour OpenAI et services compatibles
340
+ - Utilise la bibliothèque `ollama` pour communiquer avec le serveur
341
+ - Gère le streaming pour les conversations en temps réel
342
+ - Implémente un sémaphore pour limiter les requêtes d'embedding simultanées (max 4)
343
+ - Supporte tous les formats de sortie JSON structurés
351
344
 
352
- Ces classes encapsulent les détails d'implémentation spécifiques à chaque fournisseur, offrant une interface unifiée pour le reste du module. Elles gèrent les différences dans les formats de requête et de réponse, permettant à l'acteur AiAgent de fonctionner de manière transparente avec différents fournisseurs.
345
+ #### OpenAIProvider
346
+
347
+ Implémentation pour OpenAI et services compatibles (OpenRouter, etc.) :
348
+
349
+ - Utilise `RestAPI` de xcraft-core-utils pour les appels HTTP
350
+ - Adapte les formats de requête entre Ollama et OpenAI
351
+ - Gère les schémas JSON pour les réponses structurées
352
+ - Supporte les en-têtes d'authentification personnalisés
353
353
 
354
354
  ### `lib/llm/utils.js`
355
355
 
356
- Ce fichier contient diverses fonctions utilitaires pour :
356
+ Ce fichier contient un ensemble complet d'utilitaires pour le traitement de texte et de documents :
357
+
358
+ #### Traitement de documents PDF
359
+
360
+ **`getPDFImages(pdfPath)`** - Convertit les pages d'un PDF en images base64 pour l'OCR avec des options optimisées pour la qualité du texte.
361
+
362
+ **`OCR_SYSTEM_PROMPT`** - Prompt système spécialisé pour guider les modèles multimodaux dans l'extraction de texte à partir d'images.
363
+
364
+ #### Traitement de texte et HTML
365
+
366
+ **`cleanHtmlContent(html)`** - Nettoie le contenu HTML en supprimant les balises et en normalisant les espaces.
367
+
368
+ **`simplifyHtml(html)`** - Simplifie le HTML en gardant uniquement les éléments sûrs via sanitize-html.
369
+
370
+ **`extractTitlesAndContent(html)`** - Extrait intelligemment les titres et le contenu d'un document HTML en préservant la structure.
371
+
372
+ **`html2chunks(html, chunkSize, chunkOverlap)`** - Découpe un document HTML en chunks en utilisant RecursiveCharacterTextSplitter de LangChain.
373
+
374
+ #### Gestion des tokens et découpage
375
+
376
+ **`estimateTokenCount(text)`** - Estime le nombre de tokens d'un texte (approximation basée sur les mots × 1.33).
377
+
378
+ **`splitLongText(text, maxLength, baseId)`** - Découpe un texte long en segments de taille maximale en préservant les mots entiers.
379
+
380
+ **`sliceText(text, chunkSize)`** - Découpe un texte en chunks en respectant les limites de phrases.
381
+
382
+ **`groupSentences(text, maxSize)`** - Groupe les phrases en chunks de taille optimale pour les modèles de langage.
383
+
384
+ #### Traitement par lots et optimisation
385
+
386
+ **`chunkArray(array, size)`** - Divise un tableau en sous-tableaux de taille spécifiée pour le traitement par lots.
387
+
388
+ **`embedChunksInBatch(agent, allChunks, batchSize)`** - Traite les embeddings par lots en associant chaque embedding à son contenu d'origine.
389
+
390
+ **`buildPromptFromArticlesMulti(initialQuestion, questionsWithArticles, maxTotalTokens)`** - Construit des prompts optimisés à partir de multiples articles en respectant les limites de tokens.
357
391
 
358
- - Extraction de texte à partir d'images PDF (`getPDFImages`)
359
- - Nettoyage et simplification de contenu HTML (`cleanHtmlContent`, `simplifyHtml`)
360
- - Découpage de texte en segments gérables (`splitLongText`, `html2chunks`)
361
- - Estimation du nombre de tokens (`estimateTokenCount`)
362
- - Construction de prompts à partir d'articles (`buildPromptFromArticles`)
363
- - Traitement par lots des embeddings (`embedChunksInBatch`, `chunkArray`)
392
+ #### Utilitaires de conversion
364
393
 
365
- Ces utilitaires sont essentiels pour préparer les données avant de les envoyer aux modèles de langage et pour traiter les résultats. Ils permettent notamment de gérer les contraintes de taille de contexte des modèles en découpant intelligemment les textes longs.
394
+ **`vectorToSqlLiteral(vec)`** - Convertit un vecteur Float32Array en littéral SQL hexadécimal pour le stockage en base de données.
366
395
 
367
- Le module inclut également des fonctionnalités spécifiques pour l'OCR (reconnaissance optique de caractères) avec un prompt système dédié (`OCR_SYSTEM_PROMPT`) qui guide les modèles multimodaux dans l'extraction de texte à partir d'images.
396
+ Ces utilitaires sont essentiels pour préparer les données avant de les envoyer aux modèles de langage et pour traiter les résultats. Ils permettent notamment de gérer les contraintes de taille de contexte des modèles en découpant intelligemment les textes longs tout en préservant la cohérence sémantique.
368
397
 
369
398
  _Cette documentation a été mise à jour automatiquement._
370
399
 
371
400
  [xcraft-core-goblin]: https://github.com/Xcraft-Inc/xcraft-core-goblin
372
401
  [xcraft-core-stones]: https://github.com/Xcraft-Inc/xcraft-core-stones
373
- [xcraft-core-utils]: https://github.com/Xcraft-Inc/xcraft-core-utils
402
+ [xcraft-core-utils]: https://github.com/Xcraft-Inc/xcraft-core-utils
403
+ [xcraft-core-etc]: https://github.com/Xcraft-Inc/xcraft-core-etc
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "goblin-agents",
3
- "version": "0.1.10",
3
+ "version": "0.1.11",
4
4
  "description": "AI Agents framework",
5
5
  "author": "Samuel Loup",
6
6
  "license": "MIT",