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.
- package/README.md +38 -2
- package/client/src/App.jsx +13 -20
- package/client/src/AssistantChat.jsx +5 -4
- package/client/src/DataEditor.jsx +1 -1
- package/client/src/DataTable.jsx +47 -3
- package/client/src/ExportDialog.jsx +2 -2
- package/client/src/Field.jsx +2 -2
- package/client/src/KanbanCard.jsx +4 -2
- package/client/src/KanbanConfigModal.jsx +5 -7
- package/client/src/ModelCreatorField.jsx +9 -9
- package/client/src/PackGallery.jsx +89 -9
- package/client/src/PackGallery.scss +58 -4
- package/client/src/RTETrans.jsx +11 -0
- package/client/src/RelationValue.jsx +3 -4
- package/client/src/constants.js +1 -1
- package/client/src/core/data.js +2 -1
- package/client/src/translations.js +63 -0
- package/package.json +8 -1
- package/server.js +4 -4
- package/src/constants.js +6 -0
- package/src/defaultModels.js +23 -10
- package/src/i18n.js +1 -1
- package/src/modules/{assistant.js → assistant/assistant.js} +42 -27
- package/src/modules/assistant/constants.js +16 -0
- package/src/modules/data/data.js +4601 -4552
- package/src/modules/data/data.routes.js +29 -3
- package/src/modules/user.js +12 -1
- package/src/modules/workflow.js +133 -48
- package/src/packs.js +1015 -9
- package/src/services/index.js +11 -0
- package/src/services/stripe.js +141 -0
- package/test/data.integration.test.js +65 -2
- package/test/workflow.actions.integration.test.js +2 -2
- package/test/workflow.integration.test.js +1 -1
package/client/src/RTETrans.jsx
CHANGED
|
@@ -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
|
-
|
|
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={
|
|
200
|
-
name={f.name} value={
|
|
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
|
}
|
package/client/src/constants.js
CHANGED
package/client/src/core/data.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
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.
|
|
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
|
|
31
|
-
engine.start(
|
|
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 " +
|
|
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
|
+
}
|
package/src/defaultModels.js
CHANGED
|
@@ -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', '
|
|
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
|
|
927
|
-
{ name: '
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
{ name: '
|
|
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
|
-
"
|
|
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 "
|
|
2
|
-
import { Logger } from "
|
|
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 "
|
|
7
|
-
import { getDataAsString } from "
|
|
8
|
-
import i18n from "../../
|
|
9
|
-
import {generateLimiter} from "
|
|
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 "
|
|
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 ('
|
|
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 || '
|
|
243
|
-
const
|
|
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 ${
|
|
252
|
-
|
|
253
|
-
llm = p
|
|
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('
|
|
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
|
+
};
|