data-primals-engine 1.6.5 → 1.7.1

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 (40) hide show
  1. package/README.md +160 -113
  2. package/client/index.js +3 -0
  3. package/client/package-lock.json +8121 -8824
  4. package/client/package.json +10 -3
  5. package/client/src/AssistantChat.jsx +369 -362
  6. package/client/src/DataEditor.jsx +383 -383
  7. package/client/src/DataLayout.jsx +54 -20
  8. package/client/src/ModelList.jsx +280 -280
  9. package/client/src/ViewSwitcher.scss +0 -31
  10. package/client/src/constants.js +81 -100
  11. package/client/src/contexts/CommandContext.jsx +274 -259
  12. package/client/vite.config.js +30 -30
  13. package/doc/AI-assistance.md +93 -0
  14. package/doc/Advanced-workflows.md +90 -0
  15. package/doc/Event-system.md +79 -0
  16. package/doc/Packs-gallery.md +73 -0
  17. package/package.json +30 -16
  18. package/src/constants.js +1 -1
  19. package/src/core.js +487 -477
  20. package/src/defaultModels.js +1 -1
  21. package/src/email.js +0 -2
  22. package/src/engine.js +342 -335
  23. package/src/filter.js +348 -343
  24. package/src/migrate.js +1 -1
  25. package/src/modules/assistant/assistant.js +30 -20
  26. package/src/modules/data/data.backup.js +4 -4
  27. package/src/modules/data/data.js +311 -302
  28. package/src/modules/data/data.operations.js +79 -64
  29. package/src/modules/data/data.relations.js +2 -1
  30. package/src/modules/data/data.scheduling.js +1 -1
  31. package/src/modules/mongodb.js +16 -8
  32. package/src/modules/user.js +0 -1
  33. package/src/modules/workflow.js +1828 -1815
  34. package/src/packs.js +5701 -5697
  35. package/src/profiles.js +19 -0
  36. package/swagger-en.yml +3390 -3385
  37. package/swagger-fr.yml +3385 -3380
  38. package/test/assistant.test.js +2 -2
  39. package/test/data.backup.integration.test.js +3 -1
  40. package/test/data.history.integration.test.js +0 -1
package/src/migrate.js CHANGED
@@ -24,7 +24,7 @@ engine.start(port, async () => {
24
24
  const target = process.argv[3]; // Le nom du fichier de migration cible
25
25
 
26
26
  try {
27
- const db = MongoDatabase;
27
+ const db = MongoDatabase();
28
28
  const { executedNames, allMigrationFiles } = await getMigrationStatus(db);
29
29
 
30
30
  switch (command) {
@@ -8,7 +8,7 @@ import {Config} from "../../config.js";
8
8
  import { Event } from "../../events.js";
9
9
  import rateLimit from "express-rate-limit";
10
10
  import {generateLimiter} from "../user.js";
11
- import {assistantConfig, maxAIReflectiveSteps} from "../../constants.js";
11
+ import {maxAIReflectiveSteps} from "../../constants.js";
12
12
  import i18n from "../../i18n.js";
13
13
  import {parseSafeJSON} from "../../core.js";
14
14
 
@@ -80,16 +80,15 @@ REGLE FONDATRICE : suis les règles et ne dévie pas du chemin.
80
80
  STYLE UTILISE : apporte l'information au plus rapide, sans détours, ni sollicitation à l'utilisateur, ou à des tiers.
81
81
 
82
82
  FORMAT DE RÉPONSE OBLIGATOIRE :
83
- Ta réponse DOIT être un objet JSON unique OU un tableau d'objets JSON. Chaque objet doit contenir exactement 2 champs :
83
+ Ta réponse DOIT être un tableau d'objets JSON (Même pour une seule action). Chaque objet doit contenir exactement 2 champs :
84
84
  1. "action" (string)
85
85
  2. "params" (object)
86
86
 
87
- - Pour une action simple, retourne un objet : { "action": "...", "params": {...} }
88
- - Pour enchaîner plusieurs actions, retourne un tableau :
89
- [
90
- { "action": "search_models", "params": {"query": "..."} },
91
- { "action": "displayMessage", "params": { "message": "Je cherche les modèles..." } }
92
- ]
87
+ Exemple :
88
+ [
89
+ { "action": "search_models", "params": {"query": "..."} },
90
+ { "action": "displayMessage", "params": { "message": "Je cherche les modèles..." } }
91
+ ]
93
92
 
94
93
  Tu as accès aux outils et actions suivants.
95
94
 
@@ -529,7 +528,7 @@ export async function handleChatRequest(params, user, sendEvent = null) {
529
528
  }
530
529
 
531
530
  const toolResults = [];
532
- let finalActionResult = null;
531
+ const finalActionResults = [];
533
532
 
534
533
  for (const command of commands) {
535
534
  logger.debug(`[Assistant] Action décidée par l'IA: ${command.action}`, command);
@@ -554,27 +553,31 @@ export async function handleChatRequest(params, user, sendEvent = null) {
554
553
  const res = await Event.Trigger('OnChatAction', 'event', 'user', action, parsedParams, command, llmOptions, user, params);
555
554
 
556
555
  if (res) {
557
- // On a trouvé une action finale. On la stocke et on arrête de chercher.
558
- finalActionResult = res;
559
- break; // Sort de la boucle des commandes
556
+ if (res.isToolResult) {
557
+ toolResults.push({ action, result: res.toolResult || res.displayMessage });
558
+ } else {
559
+ // On a trouvé une action finale. On la stocke.
560
+ finalActionResults.push(res);
561
+ }
560
562
  } else {
561
563
  // Si l'action n'est reconnue par aucune des logiques ci-dessus
562
564
  logger.warn(`[Assistant] Action non reconnue reçue de l'IA: ${action}`);
563
- finalActionResult = {
565
+ finalActionResults.push({
564
566
  success: true,
565
567
  displayMessage: i18n.t('assistant.unknownAction', "Désolé, je ne comprends pas la commande '{{action}}'.", { action })
566
- };
567
- break; // Sortir de la boucle des commandes
568
+ });
568
569
  }
569
570
  }
570
571
 
571
- // Si une action finale a été exécutée, on retourne son résultat.
572
- if (finalActionResult) {
572
+ // Si une ou plusieurs actions finales ont été exécutées, on retourne le résultat.
573
+ if (finalActionResults.length > 0) {
574
+ // Rétrocompatibilité : si un seul résultat, on renvoie l'objet directement. Sinon, on renvoie un tableau 'results'.
575
+ const response = finalActionResults.length === 1 ? finalActionResults[0] : { success: true, results: finalActionResults };
573
576
  if (sendEvent) {
574
- sendEvent('final_result', finalActionResult);
577
+ sendEvent('final_result', response);
575
578
  return;
576
579
  }
577
- return finalActionResult;
580
+ return response;
578
581
  }
579
582
 
580
583
  // Si on a uniquement des résultats d'outils, on les ajoute à l'historique et on continue la boucle.
@@ -673,7 +676,14 @@ async function handleFinalChatAction(action, params, parsedResponse, llmOptions,
673
676
 
674
677
  // Actions nécessitant une confirmation de l'utilisateur
675
678
  if (['post', 'update', 'delete'].includes(action)) {
676
- return { success: true, displayMessage: i18n.t('assistant.confirmActionPrompt', "Veuillez confirmer l'action suivante :"), confirmationRequest: parsedResponse };
679
+ return {
680
+ success: true,
681
+ displayMessage: i18n.t('assistant.confirmActionPrompt', "Veuillez confirmer l'action suivante :"),
682
+ confirmationRequest: parsedResponse,
683
+ model: params.model,
684
+ filter: params.filter,
685
+ data: params.data
686
+ };
677
687
  }
678
688
 
679
689
  // Action finale pour afficher un message
@@ -8,7 +8,7 @@ import {downloadFromS3, getUserS3Config, listS3Backups, uploadToS3} from "../buc
8
8
  import fs from "node:fs";
9
9
  import {modelsCache, runCryptoWorkerTask} from "./data.core.js";
10
10
  import * as tar from "tar";
11
- import {getCollection, getUserCollectionName, modelsCollection} from "../mongodb.js";
11
+ import {getCollection, getDatabase, getUserCollectionName, modelsCollection} from "../mongodb.js";
12
12
  import {removeFile} from "../file.js";
13
13
  import {cancelAlerts, scheduleAlerts} from "./data.scheduling.js";
14
14
  import {dbName} from "../../constants.js";
@@ -136,7 +136,7 @@ export const loadFromDump = async (user, options = {}) => {
136
136
  await tar.extract({file: backupFilePath, gzip: true, C: tmpRestoreDir, sync: true});
137
137
 
138
138
  // ... (Cleaning logic: deleteMany, removeFile, cancelAlerts) ...
139
- const datasCollection = getCollection("datas");
139
+ const datasCollection = getCollection(Config.Get('dataCollection', 'datas'));
140
140
  if (modelsOnly) {
141
141
  await modelsCollection.deleteMany({_user: user.username});
142
142
  } else {
@@ -169,7 +169,7 @@ export const loadFromDump = async (user, options = {}) => {
169
169
  args.push('--nsInclude', `${d}.models`);
170
170
  } else {
171
171
  // mongorestore accepte plusieurs fois l'option --nsInclude
172
- args.push('--nsInclude', `${d}.datas`);
172
+ args.push('--nsInclude', `${d}.${Config.Get('dataCollection', 'datas')}`);
173
173
  args.push('--nsInclude', `${d}.models`);
174
174
  }
175
175
  // Le répertoire source est le dernier argument
@@ -245,7 +245,7 @@ export const dumpUserData = async (user) => {
245
245
 
246
246
 
247
247
  const d = Config.Get('dbName', dbName);
248
- const collections = await MongoDatabase.listCollections().toArray();
248
+ const collections = await getDatabase().listCollections().toArray();
249
249
  for (const collection of collections) {
250
250
  const collsToBackup = [await getUserCollectionName(user), 'models'];
251
251
  if (collsToBackup.includes(collection.name)) {