data-primals-engine 1.2.6 → 1.3.0

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.
@@ -53,6 +53,16 @@ const RTETrans = ({ value, onChange, field }) => {
53
53
  };
54
54
  const languagesToAdd = availableLangs.filter(lang => !existingLangs.includes(lang.code));
55
55
 
56
+ const confirmDelete = (e, lang) => {
57
+ e.preventDefault();
58
+ e.stopPropagation();
59
+ if( !confirm(t('rte.confirmLangDeletion', 'Confirm lang deletion ?')))
60
+ return;
61
+ const val = {...value};
62
+ delete val[lang];
63
+ onChange(val);
64
+ setActiveTab(Object.keys(val)[0] || null);
65
+ }
56
66
  return (
57
67
  <div className="rte-trans-container">
58
68
  <div className="tabs-container flex items-center border-b border-gray-200">
@@ -64,6 +74,7 @@ const RTETrans = ({ value, onChange, field }) => {
64
74
  title={availableLangs.find(f=>f.code===lang)?.name.value || ''}
65
75
  >
66
76
  {lang.toUpperCase()}
77
+ <button onClick={(e) => confirmDelete(e, lang)}>x</button>
67
78
  </button>
68
79
  ))}
69
80
  {languagesToAdd.length > 0 && (
@@ -187,8 +187,7 @@ const RelationValue = ({ field, data, align }) => {
187
187
  if (f.type === 'code') {
188
188
  let t;
189
189
  try {
190
- t = f.language === 'json' ? JSON.stringify(intVal[f.name], null, 2) : '';
191
-
190
+ t = f.language === 'json' ? JSON.stringify(intVal[f.name], null, 2) : t = intVal[f.name].toString();
192
191
  } catch (e) {
193
192
  t = intVal[f.name].toString();
194
193
  }
@@ -196,8 +195,8 @@ const RelationValue = ({ field, data, align }) => {
196
195
  <dt>{columnName} {span}</dt>
197
196
  <dd>
198
197
  <CodeField onChange={() => {
199
- }} language={field.language || 'json'}
200
- name={f.name} value={field.language === 'json' ? JSON.stringify(intVal[f.name], null, 2) : t} />
198
+ }} language={f.language || 'json'}
199
+ name={f.name} value={f.language === 'json' ? JSON.stringify(intVal[f.name], null, 2) : t} />
201
200
  </dd>
202
201
  </>;
203
202
  }
@@ -65,7 +65,7 @@ export const OPERAND_TYPES = {
65
65
 
66
66
 
67
67
  export const getHost = () => {
68
- return process.env.HOST || host || 'localhost';
68
+ return import.meta.env.HOST || host || 'localhost';
69
69
  }
70
70
 
71
71
 
@@ -1,4 +1,5 @@
1
- import {getHost, MONGO_OPERATORS} from "../constants.js";
1
+ import { MONGO_OPERATORS} from "../constants.js";
2
+ import {getHost} from "../../../src/constants";
2
3
 
3
4
  const isProd = import.meta.env.MODE === 'production';
4
5
  export const urlData = isProd ? 'https://'+getHost()+'/' : 'http://localhost:7633/';
@@ -3,6 +3,14 @@ export const websiteTranslations = {
3
3
  fr: {
4
4
  translation: {
5
5
 
6
+ "field_endpoint_isPublic": "Accès public",
7
+ "field_endpoint_isPublic_hint": "Si coché, ce point d'accès sera accessible sans authentification. Le script s'exécutera avec les droits du propriétaire du point d'accès.",
8
+
9
+ "packs.manualInstall": "Importer",
10
+ "packs.manualInstall.title": "Installation manuelle de pack",
11
+ "packs.manualInstall.instructions": "Collez ici le JSON de configuration du pack que vous souhaitez installer.",
12
+ "packs.manualInstall.placeholder": "{\"name\": \"Mon Pack\", \"description\": \"...\", \"models\": [...], \"data\": [...]}",
13
+
6
14
  "api.data.relationFilterFailed": "La valeur {{value}} pour le champ {{field}} ne respecte pas le filtre de relation défini.",
7
15
 
8
16
  "dataimporter.excelPreview":"Aperçu des données Excel",
@@ -535,6 +543,11 @@ export const websiteTranslations = {
535
543
  },
536
544
  en: {
537
545
  translation: {
546
+ "packs.manualInstall": "Import",
547
+ "packs.manualInstall.title": "Manual Pack Installation",
548
+ "packs.manualInstall.instructions": "Paste the configuration JSON of the pack you want to install here.",
549
+ "packs.manualInstall.placeholder": "{\"name\": \"My Pack\", \"description\": \"...\", \"models\": [...], \"data\": [...]}",
550
+
538
551
  "dataimporter.excelPreview": "Excel Data Preview",
539
552
  "dataimporter.previewNote": "Note: This is a preview of the first few rows. Empty cells are displayed as \"(empty)\".",
540
553
  "dataimporter.nullValue": "(empty)",
@@ -1944,6 +1957,11 @@ export const websiteTranslations = {
1944
1957
  },
1945
1958
  es: {
1946
1959
  translation: {
1960
+ "packs.manualInstall": "Importar",
1961
+ "packs.manualInstall.title": "Instalación manual del paquete",
1962
+ "packs.manualInstall.instructions": "Pegue aquí el JSON de configuración del paquete que desea instalar.",
1963
+ "packs.manualInstall.placeholder": "{\"name\": \"Mi paquete\", \"description\": \"...\", \"models\": [...], \"data\": [...]}",
1964
+
1947
1965
  "dataimporter.excelPreview": "Vista previa de datos de Excel",
1948
1966
  "dataimporter.previewNote": "Nota: Esta es una vista previa de las primeras filas. Las celdas vacías se muestran como \"(vacío)\".",
1949
1967
  "dataimporter.nullValue": "(vacío)",
@@ -3357,6 +3375,11 @@ export const websiteTranslations = {
3357
3375
  },
3358
3376
  pt: {
3359
3377
  translation: {
3378
+ "packs.manualInstall": "Importar",
3379
+ "packs.manualInstall.title": "Instalação manual do pacote",
3380
+ "packs.manualInstall.instructions": "Cole o JSON de configuração do pacote que você deseja instalar aqui.",
3381
+ "packs.manualInstall.placeholder": "{\"name\": \"Meu pacote\", \"description\": \"...\", \"models\": [...], \"data\": [...]}",
3382
+
3360
3383
  "dataimporter.excelPreview": "Visualização de Dados do Excel",
3361
3384
  "dataimporter.previewNote": "Observação: Esta é uma visualização das primeiras linhas. Células vazias são exibidas como \"(vazio)\".",
3362
3385
  "dataimporter.nullValue": "(vazio)",
@@ -4765,6 +4788,11 @@ export const websiteTranslations = {
4765
4788
  },
4766
4789
  de: {
4767
4790
  translation: {
4791
+ "packs.manualInstall": "Importieren",
4792
+ "packs.manualInstall.title": "Manuelle Paketinstallation",
4793
+ "packs.manualInstall.instructions": "Fügen Sie hier die JSON-Konfiguration des zu installierenden Pakets ein.",
4794
+ "packs.manualInstall.placeholder": "{\"name\": \"Mein Paket\", \"description\": \"...\", \"models\": [...], \"data\": [...]}",
4795
+
4768
4796
  "dataimporter.excelPreview": "Excel-Datenvorschau",
4769
4797
  "dataimporter.previewNote": "Hinweis: Dies ist eine Vorschau der ersten Zeilen. Leere Zellen werden als \"(leer)\" angezeigt.",
4770
4798
  "dataimporter.nullValue": "(leer)",
@@ -6157,6 +6185,11 @@ export const websiteTranslations = {
6157
6185
  },
6158
6186
  it: {
6159
6187
  translation: {
6188
+ "packs.manualInstall": "Importa",
6189
+ "packs.manualInstall.title": "Installazione manuale del pacchetto",
6190
+ "packs.manualInstall.instructions": "Incolla qui il file JSON di configurazione del pacchetto che desideri installare.",
6191
+ "packs.manualInstall.placeholder": "{\"name\": \"My Pack\", \"description\": \"...\", \"models\": [...], \"data\": [...]}",
6192
+
6160
6193
  "dataimporter.excelPreview": "Anteprima dati Excel",
6161
6194
  "dataimporter.previewNote": "Nota: questa è un'anteprima delle prime righe. Le celle vuote vengono visualizzate come \"(vuoto)\".",
6162
6195
  "dataimporter.nullValue": "(vuoto)",
@@ -7562,6 +7595,11 @@ export const websiteTranslations = {
7562
7595
  },
7563
7596
  cs: {
7564
7597
  translation: {
7598
+ "packs.manualInstall": "Importovat",
7599
+ "packs.manualInstall.title": "Ruční instalace balíčku",
7600
+ "packs.manualInstall.instructions": "Sem vložte konfigurační JSON balíčku, který chcete nainstalovat.",
7601
+ "packs.manualInstall.placeholder": "{\"name\": \"Můj balíček\", \"description\": \"...\", \"models\": [...], \"data\": [...]}",
7602
+
7565
7603
  "dataimporter.excelPreview": "Náhled dat v Excelu",
7566
7604
  "dataimporter.previewNote": "Poznámka: Toto je náhled prvních několika řádků. Prázdné buňky se zobrazují jako \"(prázdné)\".",
7567
7605
  "dataimporter.nullValue": "(prázdné)",
@@ -8962,6 +9000,11 @@ export const websiteTranslations = {
8962
9000
  },
8963
9001
  ru: {
8964
9002
  translation: {
9003
+ "packs.manualInstall": "Импорт",
9004
+ "packs.manualInstall.title": "Ручная установка пакета",
9005
+ "packs.manualInstall.instructions": "Вставьте сюда JSON-файл конфигурации пакета, который вы хотите установить.",
9006
+ "packs.manualInstall.placeholder": "{\"name\": \"My Pack\", \"description\": \"...\", \"models\": [...], \"data\": [...]}",
9007
+
8965
9008
  "dataimporter.excelPreview": "Предварительный просмотр данных Excel",
8966
9009
  "dataimporter.previewNote": "Примечание: Это предварительный просмотр первых нескольких строк. Пустые ячейки отображаются как \"(пусто)\".",
8967
9010
  "dataimporter.nullValue": "(пусто)",
@@ -10372,6 +10415,10 @@ export const websiteTranslations = {
10372
10415
  },
10373
10416
  ar: {
10374
10417
  translation: {
10418
+ "packs.manualInstall": "استيراد",
10419
+ "packs.manualInstall.title": "تثبيت الحزمة يدويًا",
10420
+ "packs.manualInstall.instructions": "الصق ملف JSON الخاص بتكوين الحزمة التي تريد تثبيتها هنا",
10421
+ "packs.manualInstall.placeholder": "{\"name\": \"My Pack\", \"description\": \"...\", \"models\": [...], \"data\": [...]}",
10375
10422
  "dataimporter.excelPreview": "معاينة بيانات إكسل",
10376
10423
  "dataimporter.previewNote": "ملاحظة: هذه معاينة للصفوف القليلة الأولى. تُعرض الخلايا الفارغة كـ \"(فارغة)\".",
10377
10424
  "dataimporter.nullValue": "(فارغة)",
@@ -11799,6 +11846,11 @@ export const websiteTranslations = {
11799
11846
  },
11800
11847
  sv: {
11801
11848
  translation: {
11849
+ "packs.manualInstall": "Importera",
11850
+ "packs.manualInstall.title": "Manuell paketinstallation",
11851
+ "packs.manualInstall.instructions": "Klistra in konfigurations-JSON-filen för paketet du vill installera här.",
11852
+ "packs.manualInstall.placeholder": "{\"namn\": \"Mitt paket\", \"beskrivning\": \"...\", \"modeller\": [...], \"data\": [...]}",
11853
+
11802
11854
  "dataimporter.excelPreview": "Förhandsgranskning av Excel-data",
11803
11855
  "dataimporter.previewNote": "Obs! Detta är en förhandsgranskning av de första raderna. Tomma celler visas som \"(tomma)\"",
11804
11856
  "dataimporter.nullValue": "(tomma)",
@@ -13199,6 +13251,11 @@ export const websiteTranslations = {
13199
13251
  },
13200
13252
  el: {
13201
13253
  translation: {
13254
+ "packs.manualInstall": "Εισαγωγή",
13255
+ "packs.manualInstall.title": "Χειροκίνητη εγκατάσταση πακέτου",
13256
+ "packs.manualInstall.instructions": "Επικολλήστε εδώ το JSON διαμόρφωσης του πακέτου που θέλετε να εγκαταστήσετε.",
13257
+ "packs.manualInstall.placeholder": "{\"name\": \"Το πακέτο μου\", \"περιγραφή\": \"...\", \"μοντέλα\": [...], \"δεδομένα\": [...]}",
13258
+
13202
13259
  "dataimporter.excelPreview": "Προεπισκόπηση δεδομένων Excel",
13203
13260
  "dataimporter.previewNote": "Σημείωση: Αυτή είναι μια προεπισκόπηση των πρώτων γραμμών. Τα κενά κελιά εμφανίζονται ως \"(κενό)\".",
13204
13261
  "dataimporter.nullValue": "(κενό)",
@@ -14607,6 +14664,12 @@ export const websiteTranslations = {
14607
14664
  },
14608
14665
  fa: {
14609
14666
  "translation": {
14667
+
14668
+ "packs.manualInstall": "وارد کردن",
14669
+ "packs.manualInstall.title": "نصب دستی بسته",
14670
+ "packs.manualInstall.instructions": "فایل JSON پیکربندی بسته‌ای که می‌خواهید نصب کنید را اینجا جای‌گذاری کنید.",
14671
+ "packs.manualInstall.placeholder": "{\"name\": \"بسته من\", \"description\": \"...\", \"models\": [...], \"data\": [...]}",
14672
+
14610
14673
  "dataimporter.excelPreview": "پیش‌نمایش داده‌های اکسل",
14611
14674
  "dataimporter.previewNote": "توجه: این پیش‌نمایشی از چند ردیف اول است. سلول‌های خالی به صورت \"(empty)\" نمایش داده می‌شوند.",
14612
14675
  "dataimporter.nullValue": "(empty)",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "data-primals-engine",
3
- "version": "1.2.6",
3
+ "version": "1.3.0",
4
4
  "description": "data-primals-engine is a package responsible from handling large amount of data using MongoDB in a practical and performant way. It can also get workflow models working (for automation), and fully supports internationalisation. It also has integrated AI assistant.",
5
5
  "main": "src/engine.js",
6
6
  "type": "module",
@@ -33,6 +33,11 @@
33
33
  "brace-expansion": "2.0.2",
34
34
  "prismjs": "1.30.0"
35
35
  },
36
+ "overrides": {
37
+ "refractor": {
38
+ "prismjs": "1.30.0"
39
+ }
40
+ },
36
41
  "repository": {
37
42
  "type": "git",
38
43
  "url": "https://github.com/anonympins/data-primals-engine.git"
@@ -50,6 +55,7 @@
50
55
  "react-query": ">=3.0.0"
51
56
  },
52
57
  "dependencies": {
58
+ "@langchain/anthropic": "^0.3.26",
53
59
  "@langchain/core": "^0.3.66",
54
60
  "@langchain/deepseek": "^0.1.0",
55
61
  "@langchain/google-genai": "^0.2.16",
@@ -88,6 +94,7 @@
88
94
  "request-ip": "^3.3.0",
89
95
  "sanitize-html": "^2.17.0",
90
96
  "sirv": "^3.0.1",
97
+ "stripe": "^18.4.0",
91
98
  "swagger-ui-express": "^5.0.1",
92
99
  "tar": "^7.4.3",
93
100
  "uniqid": "^5.4.0",
package/server.js CHANGED
@@ -7,6 +7,7 @@ import process from "node:process";
7
7
  import {Config, Engine, BenchmarkTool, GameObject, Logger} from "./src/index.js";
8
8
  import sirv from "sirv";
9
9
  import express from "express";
10
+ import {port} from "./src/constants.js";
10
11
 
11
12
  Config.Set("modules", ["mongodb", "data", "file", "bucket", "workflow","user", "assistant", "swagger"])
12
13
  Config.Set("middlewares", []);
@@ -27,10 +28,9 @@ if (process.argv.length === 3) {
27
28
  }
28
29
 
29
30
 
30
- const port = process.env.PORT || 7633;
31
- engine.start(port, async (r) => {
31
+ const realPort = process.env.PORT || port;
32
+ engine.start(realPort, async (r) => {
32
33
  const logger = engine.getComponent(Logger);
33
- console.log("Server started on port " + port);
34
+ console.log("Server started on port " + realPort);
34
35
  timer.stop();
35
-
36
36
  });
package/src/constants.js CHANGED
@@ -24,6 +24,8 @@ export const dbName = "engine";
24
24
  */
25
25
  export const host = 'localhost'; // or myhost.tld
26
26
 
27
+ export const port = 7633;
28
+
27
29
  /**
28
30
  * Cookie secret key (if COOKIES_SECRET is set, it will override this variable)
29
31
  * @type {string}
@@ -301,3 +303,7 @@ metaModels['erp'] = { load: [ 'accountingExercise', 'accountingLineItem', 'accou
301
303
  export const allowedFields = ['locked', 'hiddenable', 'anonymized', 'condition', 'color', 'index', 'type', 'required', 'hint', 'default', 'validate', 'unique', 'name', 'placeholder', 'asMain'];
302
304
 
303
305
 
306
+
307
+ export const getHost = () => {
308
+ return process.env.HOST || host || 'localhost';
309
+ }
@@ -420,6 +420,7 @@ export const defaultModels = {
420
420
  { "name": "products", "type": "relation", "relation": "cartItem", "required": true, multiple: true },
421
421
  { "name": "customer", "type": "relation", relation: 'user' }, // Relation vers le modèle 'user'
422
422
  { "name": "totalAmount", "type": "number", "required": true },
423
+ { "name": "paymentIntentId", "type": "string", "hint": "Stripe Payment Intent ID for this order." },
423
424
  { "name": "currency", "type": "relation", "relation": "currency" },
424
425
  { "name": "paymentMethod", "type": "string" },
425
426
  { "name": "shippingAddress", "type": "relation", "relation": "location" },
@@ -506,6 +507,7 @@ export const defaultModels = {
506
507
  name: "return",
507
508
  "description": "",
508
509
  fields: [
510
+ { "name": "order", "type": "relation", "relation": "order", "required": true },
509
511
  { "name": "user", "type": "relation", relation: "user" },
510
512
  { "name": "reason", "type": "string", maxlength: 2048, required: true },
511
513
  { "name": "channel", "type": "relation", relation: 'channel' },
@@ -897,7 +899,7 @@ export const defaultModels = {
897
899
  name: 'type',
898
900
  type: 'enum',
899
901
  required: true,
900
- items: ['UpdateData', 'CreateData', 'DeleteData', 'ExecuteScript', 'CallWebhook', 'SendEmail', 'Wait', 'GenerateAIContent'],
902
+ items: ['UpdateData', 'CreateData', 'DeleteData', 'ExecuteScript', 'HttpRequest', 'SendEmail', 'Wait', 'GenerateAIContent', 'ExecuteServiceFunction'],
901
903
  hint: "The type of operation to perform."
902
904
  },
903
905
  // For UpdateData / CreateData / DeleteData
@@ -923,14 +925,11 @@ export const defaultModels = {
923
925
  // For CreateData
924
926
  { name: 'dataToCreate', condition: {$eq: ["$type", "CreateData"]}, type: 'code', language: 'json', default: {}, hint: "Object template for the new document to create" },
925
927
 
926
- // For ExecuteScript
927
- { name: 'script', condition: {$eq: ["$type", "ExecuteScript"]}, type: 'code', hint: "The script to execute." },
928
-
929
- // For CallWebhook
930
- { name: 'url', condition: {$eq: ["$type", "CallWebhook"]}, type: 'string', hint: "The URL to call." },
931
- { name: 'method', condition: {$eq: ["$type", "CallWebhook"]}, type: 'enum', items: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'], default: 'POST', hint: "HTTP method." },
932
- { name: 'headers', condition: {$eq: ["$type", "CallWebhook"]}, type: 'code', language: 'json',default: {}, hint: "HTTP headers as key-value pairs." },
933
- { name: 'body', condition: {$eq: ["$type", "CallWebhook"]}, type: 'code', language: 'json',default: {}, hint: "Request body, can include variables." },
928
+ // For HttpRequest
929
+ { name: 'url', condition: {$eq: ["$type", "HttpRequest"]}, type: 'string', hint: "The URL to call." },
930
+ { name: 'method', condition: {$eq: ["$type", "HttpRequest"]}, type: 'enum', items: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'], default: 'POST', hint: "HTTP method." },
931
+ { name: 'headers', condition: {$eq: ["$type", "HttpRequest"]}, type: 'code', language: 'json',default: {}, hint: "HTTP headers as key-value pairs." },
932
+ { name: 'body', condition: {$eq: ["$type", "HttpRequest"]}, type: 'code', language: 'json',default: {}, hint: "Request body, can include variables." },
934
933
 
935
934
  // For SendEmail
936
935
  {
@@ -977,7 +976,15 @@ export const defaultModels = {
977
976
  condition: { $eq: ["$type", "GenerateAIContent"] },
978
977
  type: 'richtext', // richtext est bien pour les longs prompts
979
978
  hint: "Le modèle de prompt. Utilise des variables comme {triggerData.field} ou {context.variable}."
980
- }
979
+ },
980
+
981
+ // For ExecuteScript
982
+ { name: 'script', condition: {$eq: ["$type", "ExecuteScript"]}, type: 'code', language: 'javascript', hint: "The script to execute." },
983
+
984
+ // For ExecuteServiceFunction
985
+ { name: 'serviceName', condition: {$eq: ["$type", "ExecuteServiceFunction"]}, type: 'string', hint: "The name of the registered service to call (e.g., 'stripe')." },
986
+ { name: 'functionName', condition: {$eq: ["$type", "ExecuteServiceFunction"]}, type: 'string', hint: "The name of the function to execute within the service." },
987
+ { name: 'args', condition: {$eq: ["$type", "ExecuteServiceFunction"]}, type: 'code', language: 'json', default: [], hint: "An array of arguments to pass to the function. Can include variables." }
981
988
 
982
989
  ]
983
990
  },
@@ -1447,6 +1454,12 @@ export const defaultModels = {
1447
1454
  default: "POST",
1448
1455
  hint: "The HTTP method required to call this endpoint."
1449
1456
  },
1457
+ {
1458
+ name: 'isPublic',
1459
+ type: 'boolean',
1460
+ default: false,
1461
+ hint: "Si coché, ce point d'accès sera accessible sans authentification."
1462
+ },
1450
1463
  {
1451
1464
  name: "code",
1452
1465
  type: "code",
package/src/i18n.js CHANGED
@@ -1121,7 +1121,7 @@ export const translations = {
1121
1121
  "CreateData": "Créer une donnée",
1122
1122
  "DeleteData": "Supprimer une donnée",
1123
1123
  "ExecuteScript": "Exécuter un script",
1124
- "CallWebhook": "Appeler un Webhook",
1124
+ "HttpRequest": "Appeler un Webhook",
1125
1125
  "SendEmail": "Envoyer un Email",
1126
1126
  "Wait": "Attendre",
1127
1127
  "GenerateAIContent": "Générer un contenu IA",
@@ -1,17 +1,45 @@
1
- import { getCollectionForUser, modelsCollection } from "./mongodb.js";
2
- import { Logger } from "../gameObject.js";
1
+ import { getCollectionForUser, modelsCollection } from "../mongodb.js";
2
+ import { Logger } from "../../gameObject.js";
3
3
  import { ChatOpenAI } from "@langchain/openai";
4
4
  import { ChatGoogleGenerativeAI } from "@langchain/google-genai";
5
5
  import { HumanMessage, SystemMessage } from "@langchain/core/messages";
6
- import {searchData, patchData, deleteData, insertData} from "./data/index.js";
7
- import { getDataAsString } from "../data.js";
8
- import i18n from "../../src/i18n.js";
9
- import {generateLimiter} from "./user.js";
6
+ import {searchData, patchData, deleteData, insertData} from "../data/index.js";
7
+ import { getDataAsString } from "../../data.js";
8
+ import i18n from "../../i18n.js";
9
+ import {generateLimiter} from "../user.js";
10
10
  import rateLimit from "express-rate-limit";
11
- import {maxAIReflectiveSteps} from "../constants.js";
11
+ import {maxAIReflectiveSteps} from "../../constants.js";
12
+ import {providers} from "./constants.js";
13
+ import {ChatDeepSeek} from "@langchain/deepseek";
14
+ import {ChatAnthropic} from "@langchain/anthropic";
12
15
 
13
16
  let logger = null;
14
17
 
18
+ export const getAIProvider= (aiProvider, aiModel, apiKey)=>{
19
+ let llm;
20
+ try {
21
+ switch (aiProvider) {
22
+ case 'OpenAI':
23
+ llm = new ChatOpenAI({apiKey, model: aiModel, temperature: 0.7});
24
+ break;
25
+ case 'Google':
26
+ llm = new ChatGoogleGenerativeAI({apiKey, model: aiModel, temperature: 0.7});
27
+ break;
28
+ case 'DeepSeek':
29
+ llm = new ChatDeepSeek({apiKey, model: aiModel, temperature: 0.7});
30
+ break;
31
+ case 'Anthropic':
32
+ llm = new ChatAnthropic({apiKey, model: aiModel, temperature: 0.7});
33
+ break;
34
+ default:
35
+ throw new Error(`Unsupported AI provider: ${aiProvider}`);
36
+ }
37
+ return llm;
38
+ }
39
+ catch (e) {
40
+ return null;
41
+ }
42
+ }
15
43
  export const assistantGlobalLimiter = rateLimit({
16
44
  windowMs: 15 * 60 * 1000, // Fenêtre de 15 minutes
17
45
  max: 100, // Limite à 100 requêtes globales pour l'assistant pendant la fenêtre (vous pouvez ajuster cette valeur)
@@ -207,7 +235,7 @@ async function executeTool(action, params, user, allModels) {
207
235
  * soit en lançant la boucle de raisonnement de l'IA.
208
236
  * @param {string} message - Le message de l'utilisateur.
209
237
  * @param {Array} history - L'historique de la conversation.
210
- * @param {string} provider - Le fournisseur d'IA ('openai' ou 'google').
238
+ * @param {string} provider - Le fournisseur d'IA ('OpenAI' ou 'google').
211
239
  * @param {object} context - Contexte additionnel.
212
240
  * @param {object} user - L'objet utilisateur.
213
241
  * @param {object} confirmedAction - Une action pré-approuvée par l'utilisateur.
@@ -239,30 +267,17 @@ async function handleChatRequest(message, history, provider, context, user, conf
239
267
  // --- INITIALISATION DE L'IA ---
240
268
  let llm;
241
269
  try {
242
- const p = provider || 'openai';
243
- const providers = {"openai": "OPENAI_API_KEY", "google": "GOOGLE_API_KEY"};
244
- const envKeyName = providers[p];
270
+ const p = provider || 'OpenAI';
271
+ const envKeyName = providers[p].key;
245
272
  if (!envKeyName) return {success: false, message: `Fournisseur IA non supporté : ${p}`};
246
273
 
247
274
  const envCollection = await getCollectionForUser(user);
248
275
  const userEnvVar = await envCollection.findOne({_model: 'env', name: envKeyName, _user: user.username});
249
276
  const apiKey = userEnvVar?.value || process.env[envKeyName];
250
277
 
251
- if (!apiKey) return {success: false, message: `Clé API pour ${provider} (${envKeyName}) non trouvée.`};
252
-
253
- llm = p === 'openai'
254
- ? new ChatOpenAI({
255
- apiKey,
256
- modelName: "gpt-4o-mini",
257
- temperature: 0.2,
258
- response_format: {"type": "json_object"}
259
- })
260
- : new ChatGoogleGenerativeAI({
261
- apiKey,
262
- modelName: "gemini-1.5-pro-latest",
263
- temperature: 0.2,
264
- response_format: {"type": "json_object"}
265
- });
278
+ if (!apiKey) return {success: false, message: `Clé API pour ${p} (${envKeyName}) non trouvée.`};
279
+
280
+ llm = getAIProvider(p, providers[p]?.defaultModel, apiKey);
266
281
  } catch (initError) {
267
282
  logger.error(`[Assistant] Erreur d'initialisation du client IA: ${initError.message}`);
268
283
  return {success: false, message: `Erreur d'initialisation du client IA: ${initError.message}`};
@@ -371,7 +386,7 @@ async function executeConfirmedAction(action, params, user) {
371
386
  export async function onInit(engine) {
372
387
  logger = engine.getComponent(Logger);
373
388
 
374
- const {middlewareAuthenticator, userInitiator} = await import('./user.js');
389
+ const {middlewareAuthenticator, userInitiator} = await import('../user.js');
375
390
 
376
391
  engine.post('/api/assistant/chat', [middlewareAuthenticator, userInitiator, assistantGlobalLimiter, generateLimiter], async (req, res) => {
377
392
  // On récupère TOUTES les propriétés du body, y compris l'action confirmée
@@ -0,0 +1,16 @@
1
+
2
+ export const providers = {
3
+ "OpenAI" : {
4
+ key:"OPENAI_API_KEY",
5
+ defaultModel: 'gpt-3.5-turbo'
6
+ },
7
+ "Google": {
8
+ key:"GOOGLE_API_KEY"
9
+ },
10
+ "DeepSeek": {
11
+ key: "DEEPSEEK_API_KEY"
12
+ },
13
+ "Anthropic": {
14
+ key:"ANTHROPIC_API_KEY"
15
+ }
16
+ };