@tiledesk/tiledesk-server 2.9.32 → 2.9.33
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +8 -0
- package/config/labels/widget.json +15 -0
- package/deploy.sh +1 -1
- package/models/kb_setting.js +53 -1
- package/package.json +2 -2
- package/routes/kb.js +205 -35
- package/services/openaiService.js +6 -2
- package/test/kbRoute.js +319 -37
package/CHANGELOG.md
CHANGED
@@ -5,6 +5,14 @@
|
|
5
5
|
🚀 IN PRODUCTION 🚀
|
6
6
|
(https://www.npmjs.com/package/@tiledesk/tiledesk-server/v/2.3.77)
|
7
7
|
|
8
|
+
# 2.10.0
|
9
|
+
- Added support for engine to namespace
|
10
|
+
- Added support for advanced context to kb
|
11
|
+
- Added support for scrape types to kb
|
12
|
+
- Updated tybot-connector to 0.2.112
|
13
|
+
- Updated vxml-connector to 0.1.54
|
14
|
+
- Updated widget.json translation file
|
15
|
+
|
8
16
|
# 2.9.32
|
9
17
|
- Added voice filters in get requests
|
10
18
|
- Added endpoint to get all projects
|
@@ -61,6 +61,7 @@
|
|
61
61
|
"CLOSE_CHAT": "Close chat",
|
62
62
|
"MINIMIZE":"Minimize",
|
63
63
|
"MAXIMIZE":"Maximize",
|
64
|
+
"CONFIRM_CLOSE_CHAT":"Are you sure you wanna close this chat?",
|
64
65
|
|
65
66
|
"INFO_SUPPORT_USER_ADDED_SUBJECT":"you",
|
66
67
|
"INFO_SUPPORT_USER_ADDED_YOU_VERB":"you have been added ",
|
@@ -160,6 +161,7 @@
|
|
160
161
|
"CLOSE_CHAT": "Chiudi chat",
|
161
162
|
"MINIMIZE":"Minimizza",
|
162
163
|
"MAXIMIZE":"Massimizza",
|
164
|
+
"CONFIRM_CLOSE_CHAT":"Vuoi davvero chiudere questa chat?",
|
163
165
|
|
164
166
|
"INFO_SUPPORT_USER_ADDED_SUBJECT":"tu",
|
165
167
|
"INFO_SUPPORT_USER_ADDED_YOU_VERB":"sei stato aggiunto ",
|
@@ -259,6 +261,7 @@
|
|
259
261
|
"CLOSE_CHAT": "Fermer le chat",
|
260
262
|
"MINIMIZE":"Minimiser",
|
261
263
|
"MAXIMIZE":"Maximiser",
|
264
|
+
"CONFIRM_CLOSE_CHAT":"Etes-vous sûr de vouloir fermer cette discussion?",
|
262
265
|
|
263
266
|
"INFO_SUPPORT_USER_ADDED_SUBJECT":"toi",
|
264
267
|
"INFO_SUPPORT_USER_ADDED_YOU_VERB":"ont été ajoutés à ",
|
@@ -358,6 +361,7 @@
|
|
358
361
|
"CLOSE_CHAT": "Cerrar chat",
|
359
362
|
"MINIMIZE":"Minimizar",
|
360
363
|
"MAXIMIZE":"Maximizar",
|
364
|
+
"CONFIRM_CLOSE_CHAT":"¿Estás segura de que quieres cerrar este chat?",
|
361
365
|
|
362
366
|
"INFO_SUPPORT_USER_ADDED_SUBJECT":"tú",
|
363
367
|
"INFO_SUPPORT_USER_ADDED_YOU_VERB":"han sido agregados a ",
|
@@ -457,6 +461,7 @@
|
|
457
461
|
"CLOSE_CHAT": "Chat schließen",
|
458
462
|
"MINIMIZE":"Minimieren",
|
459
463
|
"MAXIMIZE":"Maximieren",
|
464
|
+
"CONFIRM_CLOSE_CHAT":"Möchten Sie diesen Chat wirklich schließen?",
|
460
465
|
|
461
466
|
"INFO_SUPPORT_USER_ADDED_SUBJECT": "Sie",
|
462
467
|
"INFO_SUPPORT_USER_ADDED_YOU_VERB": "Sie wurden hinzugefügt ",
|
@@ -556,6 +561,7 @@
|
|
556
561
|
"CLOSE_CHAT": "Fechar bate-papo",
|
557
562
|
"MINIMIZE":"Minimizar",
|
558
563
|
"MAXIMIZE":"Maximizar",
|
564
|
+
"CONFIRM_CLOSE_CHAT":"Tem certeza de que deseja fechar este bate-papo?",
|
559
565
|
|
560
566
|
"INFO_SUPPORT_USER_ADDED_SUBJECT": "você",
|
561
567
|
"INFO_SUPPORT_USER_ADDED_YOU_VERB": "você foi adicionado ",
|
@@ -655,6 +661,7 @@
|
|
655
661
|
"CLOSE_CHAT": "Закрыть чат",
|
656
662
|
"MINIMIZE":"Свести к минимуму",
|
657
663
|
"MAXIMIZE":"Максимизировать",
|
664
|
+
"CONFIRM_CLOSE_CHAT":"Вы уверены, что хотите закрыть этот чат?",
|
658
665
|
|
659
666
|
"INFO_SUPPORT_USER_ADDED_SUBJECT": "вы",
|
660
667
|
"INFO_SUPPORT_USER_ADDED_YOU_VERB": "вы добавлены ",
|
@@ -754,6 +761,7 @@
|
|
754
761
|
"CLOSE_CHAT": "Sohbeti kapat",
|
755
762
|
"MINIMIZE":"Küçült",
|
756
763
|
"MAXIMIZE":"Büyüt",
|
764
|
+
"CONFIRM_CLOSE_CHAT":"Bu sohbeti kapatmak istediğinizden emin misiniz?",
|
757
765
|
|
758
766
|
"INFO_SUPPORT_USER_ADDED_SUBJECT": "siz",
|
759
767
|
"INFO_SUPPORT_USER_ADDED_YOU_VERB": "eklendiniz ",
|
@@ -855,6 +863,7 @@
|
|
855
863
|
"CLOSE_CHAT": "Затвори ћаскање",
|
856
864
|
"MINIMIZE":"Минимизирајте",
|
857
865
|
"MAXIMIZE":"Максимизирајте",
|
866
|
+
"CONFIRM_CLOSE_CHAT":"Да ли сте сигурни да желите да затворите ово ћаскање?",
|
858
867
|
|
859
868
|
"INFO_SUPPORT_USER_ADDED_SUBJECT":"ти",
|
860
869
|
"INFO_SUPPORT_USER_ADDED_YOU_VERB":"додани сте",
|
@@ -956,6 +965,7 @@
|
|
956
965
|
"CLOSE_CHAT": "إغلاق الدردشة",
|
957
966
|
"MINIMIZE":"تصغير",
|
958
967
|
"MAXIMIZE":"تحقيق أقصى قدر",
|
968
|
+
"CONFIRM_CLOSE_CHAT":"هل أنت متأكد أنك تريد إغلاق هذه الدردشة؟",
|
959
969
|
|
960
970
|
"INFO_SUPPORT_USER_ADDED_SUBJECT": "أنت",
|
961
971
|
"INFO_SUPPORT_USER_ADDED_YOU_VERB": "لقد تم اضافتك ",
|
@@ -1057,6 +1067,7 @@
|
|
1057
1067
|
"CLOSE_CHAT": "Закрити чат",
|
1058
1068
|
"MINIMIZE":"Згорнути",
|
1059
1069
|
"MAXIMIZE":"Максимізувати",
|
1070
|
+
"CONFIRM_CLOSE_CHAT":"Ви впевнені, що бажаєте закрити цей чат?",
|
1060
1071
|
|
1061
1072
|
"INFO_SUPPORT_USER_ADDED_SUBJECT": "ти",
|
1062
1073
|
"INFO_SUPPORT_USER_ADDED_YOU_VERB": "вас додали ",
|
@@ -1157,6 +1168,7 @@
|
|
1157
1168
|
"CLOSE_CHAT":"Stäng chatten",
|
1158
1169
|
"MINIMIZE":"Minimera",
|
1159
1170
|
"MAXIMIZE":"Maximera",
|
1171
|
+
"CONFIRM_CLOSE_CHAT":"Är du säker på att du vill stänga den här chatten?",
|
1160
1172
|
|
1161
1173
|
"INFO_SUPPORT_USER_ADDED_SUBJECT": "du",
|
1162
1174
|
"INFO_SUPPORT_USER_ADDED_YOU_VERB": "du har lagts till ",
|
@@ -1257,6 +1269,7 @@
|
|
1257
1269
|
"CLOSE_CHAT":"Чатты жабу",
|
1258
1270
|
"MINIMIZE":"Кішірейту",
|
1259
1271
|
"MAXIMIZE":"Үлкейту",
|
1272
|
+
"CONFIRM_CLOSE_CHAT":"Бұл чатты шынымен жапқыңыз келе ме?",
|
1260
1273
|
|
1261
1274
|
"INFO_SUPPORT_USER_ADDED_SUBJECT": "сен",
|
1262
1275
|
"INFO_SUPPORT_USER_ADDED_YOU_VERB": "сіз қосылдыңыз ",
|
@@ -1357,6 +1370,7 @@
|
|
1357
1370
|
"CLOSE_CHAT":"Chatni yopish",
|
1358
1371
|
"MINIMIZE":"Minimallashtirish",
|
1359
1372
|
"MAXIMIZE":"Maksimallashtirish",
|
1373
|
+
"CONFIRM_CLOSE_CHAT":"Bu chatni yopmoqchi ekanligingizga ishonchingiz komilmi?",
|
1360
1374
|
|
1361
1375
|
"INFO_SUPPORT_USER_ADDED_SUBJECT": "siz",
|
1362
1376
|
"INFO_SUPPORT_USER_ADDED_YOU_VERB": "qo'shildingiz ",
|
@@ -1457,6 +1471,7 @@
|
|
1457
1471
|
"CLOSE_CHAT": "Söhbəti bağlayın",
|
1458
1472
|
"MINIMIZE":"Minimallaşdırın",
|
1459
1473
|
"MAXIMIZE":"Maksimallaşdırın",
|
1474
|
+
"CONFIRM_CLOSE_CHAT":"Bu söhbəti bağlamaq istədiyinizə əminsiniz?",
|
1460
1475
|
|
1461
1476
|
"INFO_SUPPORT_USER_ADDED_SUBJECT": "Sən",
|
1462
1477
|
"INFO_SUPPORT_USER_ADDED_YOU_VERB": "siz əlavə olundunuz ",
|
package/deploy.sh
CHANGED
package/models/kb_setting.js
CHANGED
@@ -2,6 +2,31 @@ var mongoose = require('mongoose');
|
|
2
2
|
var Schema = mongoose.Schema;
|
3
3
|
var winston = require('../config/winston');
|
4
4
|
|
5
|
+
var EngineSchema = new Schema({
|
6
|
+
name: {
|
7
|
+
type: String,
|
8
|
+
required: true
|
9
|
+
},
|
10
|
+
type: {
|
11
|
+
type: String,
|
12
|
+
required: true
|
13
|
+
},
|
14
|
+
apikey: {
|
15
|
+
type: String,
|
16
|
+
required: false
|
17
|
+
},
|
18
|
+
vector_size: {
|
19
|
+
type: Number,
|
20
|
+
required: true
|
21
|
+
},
|
22
|
+
index_name: {
|
23
|
+
type: String,
|
24
|
+
required: true
|
25
|
+
}
|
26
|
+
}, {
|
27
|
+
_id: false // This is schema is always used as an embedded object inside NamespaceSchema
|
28
|
+
})
|
29
|
+
|
5
30
|
var NamespaceSchema = new Schema({
|
6
31
|
id_project: {
|
7
32
|
type: String,
|
@@ -22,6 +47,10 @@ var NamespaceSchema = new Schema({
|
|
22
47
|
default: {
|
23
48
|
type: Boolean,
|
24
49
|
default: false
|
50
|
+
},
|
51
|
+
engine: {
|
52
|
+
type: EngineSchema,
|
53
|
+
required: false
|
25
54
|
}
|
26
55
|
}, {
|
27
56
|
timestamps: true
|
@@ -59,12 +88,34 @@ var KBSchema = new Schema({
|
|
59
88
|
status: {
|
60
89
|
type: Number,
|
61
90
|
required: false
|
91
|
+
},
|
92
|
+
scrape_type: {
|
93
|
+
type: Number,
|
94
|
+
required: false
|
95
|
+
},
|
96
|
+
scrape_options: {
|
97
|
+
type: Object,
|
98
|
+
required: false,
|
99
|
+
default: undefined,
|
100
|
+
tags_to_extract: {
|
101
|
+
type: Array,
|
102
|
+
required: false
|
103
|
+
},
|
104
|
+
unwanted_tags: {
|
105
|
+
type: Array,
|
106
|
+
required: false
|
107
|
+
},
|
108
|
+
unwanted_classnames: {
|
109
|
+
type: Array,
|
110
|
+
required: false
|
111
|
+
}
|
62
112
|
}
|
63
113
|
}, {
|
64
114
|
timestamps: true
|
65
115
|
})
|
66
116
|
|
67
117
|
|
118
|
+
|
68
119
|
// DEPRECATED !! - Start
|
69
120
|
var KBSettingSchema = new Schema({
|
70
121
|
id_project: {
|
@@ -93,7 +144,7 @@ KBSchema.index({ createdAt: -1, updatedAt: -1 })
|
|
93
144
|
|
94
145
|
// DEPRECATED
|
95
146
|
const KBSettings = mongoose.model('KBSettings', KBSettingSchema);
|
96
|
-
|
147
|
+
const Engine = mongoose.model('Engine', EngineSchema)
|
97
148
|
const Namespace = mongoose.model('Namespace', NamespaceSchema)
|
98
149
|
const KB = mongoose.model('KB', KBSchema)
|
99
150
|
|
@@ -105,5 +156,6 @@ const KB = mongoose.model('KB', KBSchema)
|
|
105
156
|
module.exports = {
|
106
157
|
KBSettings: KBSettings,
|
107
158
|
Namespace: Namespace,
|
159
|
+
Engine: Engine,
|
108
160
|
KB: KB
|
109
161
|
}
|
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "@tiledesk/tiledesk-server",
|
3
3
|
"description": "The Tiledesk server module",
|
4
|
-
"version": "2.9.
|
4
|
+
"version": "2.9.33",
|
5
5
|
"scripts": {
|
6
6
|
"start": "node ./bin/www",
|
7
7
|
"pretest": "mongodb-runner start",
|
@@ -48,7 +48,7 @@
|
|
48
48
|
"@tiledesk/tiledesk-rasa-connector": "^1.0.10",
|
49
49
|
"@tiledesk/tiledesk-telegram-connector": "^0.1.14",
|
50
50
|
"@tiledesk/tiledesk-train-jobworker": "^0.0.11",
|
51
|
-
"@tiledesk/tiledesk-tybot-connector": "^0.2.
|
51
|
+
"@tiledesk/tiledesk-tybot-connector": "^0.2.112",
|
52
52
|
"@tiledesk/tiledesk-whatsapp-connector": "^0.1.73",
|
53
53
|
"@tiledesk/tiledesk-whatsapp-jobworker": "^0.0.8",
|
54
54
|
"@tiledesk/tiledesk-sms-connector": "^0.1.10",
|
package/routes/kb.js
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
var express = require('express');
|
2
|
-
var { Namespace } = require('../models/kb_setting');
|
3
|
-
var { KB } = require('../models/kb_setting');
|
2
|
+
var { Namespace, KB, Engine } = require('../models/kb_setting');
|
3
|
+
// var { KB } = require('../models/kb_setting');
|
4
|
+
// var { Engine } = require('../models/kb_setting')
|
4
5
|
var router = express.Router();
|
5
6
|
var winston = require('../config/winston');
|
6
7
|
var multer = require('multer')
|
@@ -17,6 +18,7 @@ let Integration = require('../models/integrations');
|
|
17
18
|
var parsecsv = require("fast-csv");
|
18
19
|
|
19
20
|
const { MODELS_MULTIPLIER } = require('../utils/aiUtils');
|
21
|
+
const { body } = require('express-validator');
|
20
22
|
|
21
23
|
const AMQP_MANAGER_URL = process.env.AMQP_MANAGER_URL;
|
22
24
|
const JOB_TOPIC_EXCHANGE = process.env.JOB_TOPIC_EXCHANGE_TRAIN || 'tiledesk-trainer';
|
@@ -45,6 +47,13 @@ let default_preview_settings = {
|
|
45
47
|
//context: "You are an awesome AI Assistant."
|
46
48
|
context: null
|
47
49
|
}
|
50
|
+
let default_engine = {
|
51
|
+
name: "pinecone",
|
52
|
+
type: "pod",
|
53
|
+
apikey: "",
|
54
|
+
vector_size: 1536,
|
55
|
+
index_name: process.env.PINECONE_INDEX
|
56
|
+
}
|
48
57
|
|
49
58
|
//let default_context = "Answer if and ONLY if the answer is contained in the context provided. If the answer is not contained in the context provided ALWAYS answer with <NOANS>\n{context}"
|
50
59
|
//let default_context = "You are an helpful assistant for question-answering tasks.\nUse ONLY the following pieces of retrieved context to answer the question.\nIf you don't know the answer, just say that you don't know.\nIf none of the retrieved context answer the question, add this word to the end <NOANS>\n\n{context}";
|
@@ -68,9 +77,9 @@ router.post('/scrape/single', async (req, res) => {
|
|
68
77
|
let data = req.body;
|
69
78
|
winston.debug("/scrape/single data: ", data);
|
70
79
|
|
71
|
-
if (!data.scrape_type) {
|
72
|
-
|
73
|
-
}
|
80
|
+
// if (!data.scrape_type) {
|
81
|
+
// data.scrape_type = 1;
|
82
|
+
// }
|
74
83
|
|
75
84
|
let namespaces = await Namespace.find({ id_project: project_id }).catch((err) => {
|
76
85
|
winston.error("find namespaces error: ", err)
|
@@ -112,11 +121,28 @@ router.post('/scrape/single', async (req, res) => {
|
|
112
121
|
json.content = kb.content;
|
113
122
|
}
|
114
123
|
|
115
|
-
json.scrape_type = 1;
|
116
|
-
if (data.scrape_type) {
|
117
|
-
|
124
|
+
// json.scrape_type = 1;
|
125
|
+
// if (data.scrape_type) {
|
126
|
+
// json.scrape_type = data.scrape_type;
|
127
|
+
// }
|
128
|
+
|
129
|
+
if (kb.scrape_type) {
|
130
|
+
json.scrape_type = kb.scrape_type
|
118
131
|
}
|
119
132
|
|
133
|
+
if (kb.scrape_options) {
|
134
|
+
json.parameters_scrape_type_4 = {
|
135
|
+
tags_to_extract: kb.scrape_options.tags_to_extract,
|
136
|
+
unwanted_tags: kb.scrape_options.unwanted_tags,
|
137
|
+
unwanted_classnames: kb.scrape_options.unwanted_classnames
|
138
|
+
}
|
139
|
+
}
|
140
|
+
|
141
|
+
let ns = namespaces.find(n => n.id === kb.namespace);
|
142
|
+
json.engine = ns.engine || default_engine;
|
143
|
+
|
144
|
+
winston.verbose("/scrape/single json: ", json);
|
145
|
+
|
120
146
|
startScrape(json).then((response) => {
|
121
147
|
winston.verbose("startScrape response: ", response);
|
122
148
|
res.status(200).send(response);
|
@@ -132,6 +158,8 @@ router.post('/scrape/single', async (req, res) => {
|
|
132
158
|
|
133
159
|
router.post('/scrape/status', async (req, res) => {
|
134
160
|
|
161
|
+
let project_id = req.projectid;
|
162
|
+
// (EXAMPLE) body: { id, namespace }
|
135
163
|
let data = req.body;
|
136
164
|
winston.debug("/scrapeStatus req.body: ", req.body);
|
137
165
|
|
@@ -143,6 +171,25 @@ router.post('/scrape/status', async (req, res) => {
|
|
143
171
|
returnObject = true;
|
144
172
|
}
|
145
173
|
|
174
|
+
let namespaces = await Namespace.find({ id_project: project_id }).catch((err) => {
|
175
|
+
winston.error("find namespaces error: ", err)
|
176
|
+
res.status(500).send({ success: false, error: err })
|
177
|
+
})
|
178
|
+
|
179
|
+
if (!namespaces || namespaces.length == 0) {
|
180
|
+
let alert = "No namespace found for the selected project " + project_id + ". Cannot add content to a non-existent namespace."
|
181
|
+
winston.warn(alert);
|
182
|
+
res.status(403).send(alert);
|
183
|
+
}
|
184
|
+
|
185
|
+
let namespaceIds = namespaces.map(namespace => namespace.id);
|
186
|
+
if (!namespaceIds.includes(data.namespace)) {
|
187
|
+
return res.status(403).send({ success: false, error: "Not allowed. The namespace does not belong to the current project." })
|
188
|
+
}
|
189
|
+
|
190
|
+
let ns = namespaces.find(n => n.id === data.namespace);
|
191
|
+
data.engine = ns.engine || default_engine;
|
192
|
+
|
146
193
|
openaiService.scrapeStatus(data).then(async (response) => {
|
147
194
|
|
148
195
|
winston.debug("scrapeStatus response.data: ", response.data);
|
@@ -229,7 +276,7 @@ router.post('/qa', async (req, res) => {
|
|
229
276
|
}
|
230
277
|
|
231
278
|
// Check if "Advanced Mode" is active. In such case the default_context must be not appended
|
232
|
-
if (!data.
|
279
|
+
if (!data.advancedPrompt) {
|
233
280
|
if (data.system_context) {
|
234
281
|
data.system_context = data.system_context + " \n" + contexts[data.model];
|
235
282
|
} else {
|
@@ -237,9 +284,15 @@ router.post('/qa', async (req, res) => {
|
|
237
284
|
}
|
238
285
|
}
|
239
286
|
|
240
|
-
|
241
|
-
|
242
|
-
|
287
|
+
let ns = namespaces.find(n => n.id === data.namespace);
|
288
|
+
data.engine = ns.engine || default_engine;
|
289
|
+
|
290
|
+
delete data.advancedPrompt;
|
291
|
+
winston.verbose("ask data: ", data);
|
292
|
+
|
293
|
+
if (process.env.NODE_ENV === 'test') {
|
294
|
+
return res.status(200).send({ success: true, message: "Question skipped in test environment"});
|
295
|
+
}
|
243
296
|
|
244
297
|
openaiService.askNamespace(data).then((resp) => {
|
245
298
|
winston.debug("qa resp: ", resp.data);
|
@@ -317,6 +370,9 @@ router.delete('/delete', async (req, res) => {
|
|
317
370
|
if (!namespaceIds.includes(data.namespace)) {
|
318
371
|
return res.status(403).send({ success: false, error: "Not allowed. The namespace does not belong to the current project." })
|
319
372
|
}
|
373
|
+
|
374
|
+
let ns = namespaces.find(n => n.id === data.namespace);
|
375
|
+
data.engine = ns.engine || default_engine;
|
320
376
|
|
321
377
|
openaiService.deleteIndex(data).then((resp) => {
|
322
378
|
winston.debug("delete resp: ", resp.data);
|
@@ -352,6 +408,11 @@ router.delete('/deleteall', async (req, res) => {
|
|
352
408
|
return res.status(403).send({ success: false, error: "Not allowed. The namespace does not belong to the current project." })
|
353
409
|
}
|
354
410
|
|
411
|
+
let ns = namespaces.find(n => n.id === data.namespace);
|
412
|
+
data.engine = ns.engine || default_engine;
|
413
|
+
|
414
|
+
winston.verbose("/deleteall data: ", data);
|
415
|
+
|
355
416
|
openaiService.deleteNamespace(data).then((resp) => {
|
356
417
|
winston.debug("delete namespace resp: ", resp.data);
|
357
418
|
res.status(200).send(resp.data);
|
@@ -394,7 +455,8 @@ router.get('/namespace/all', async (req, res) => {
|
|
394
455
|
id: project_id,
|
395
456
|
name: "Default",
|
396
457
|
preview_settings: default_preview_settings,
|
397
|
-
default: true
|
458
|
+
default: true,
|
459
|
+
engine: default_engine
|
398
460
|
})
|
399
461
|
|
400
462
|
new_namespace.save((err, savedNamespace) => {
|
@@ -448,7 +510,11 @@ router.get('/namespace/:id/chunks/:content_id', async (req, res) => {
|
|
448
510
|
return res.status(403).send({ success: false, error: "Not allowed. The conten does not belong to the current namespace." })
|
449
511
|
}
|
450
512
|
|
451
|
-
|
513
|
+
let ns = namespaces.find(n => n.id === namespace_id);
|
514
|
+
let engine = ns.engine || default_engine;
|
515
|
+
delete engine._id;
|
516
|
+
|
517
|
+
openaiService.getContentChunks(namespace_id, content_id, engine).then((resp) => {
|
452
518
|
let chunks = resp.data;
|
453
519
|
winston.debug("chunks for content " + content_id);
|
454
520
|
winston.debug("chunks found ", chunks);
|
@@ -492,7 +558,6 @@ router.get('/namespace/:id/chatbots', async (req, res) => {
|
|
492
558
|
let chatbots = intents.map(i => i.id_faq_kb);
|
493
559
|
let uniqueChatbots = [...new Set(chatbots)];
|
494
560
|
|
495
|
-
|
496
561
|
let chatbotPromises = uniqueChatbots.map(async (c_id) => {
|
497
562
|
try {
|
498
563
|
let chatbot = await faq_kb.findOne({ _id: c_id, trashed: false });
|
@@ -527,6 +592,7 @@ router.post('/namespace', async (req, res) => {
|
|
527
592
|
id: namespace_id,
|
528
593
|
name: body.name,
|
529
594
|
preview_settings: default_preview_settings,
|
595
|
+
engine: default_engine
|
530
596
|
})
|
531
597
|
|
532
598
|
let namespaces = await Namespace.find({ id_project: project_id }).catch((err) => {
|
@@ -589,11 +655,23 @@ router.put('/namespace/:id', async (req, res) => {
|
|
589
655
|
|
590
656
|
router.delete('/namespace/:id', async (req, res) => {
|
591
657
|
|
592
|
-
let
|
658
|
+
let project_id = req.projectid;
|
593
659
|
let namespace_id = req.params.id;
|
594
660
|
|
661
|
+
let namespace = await Namespace.findOne({ id_project: project_id, id: namespace_id }).catch((err) => {
|
662
|
+
winston.error("find namespace error: ", err);
|
663
|
+
res.status(500).send({ success: false, error: err });
|
664
|
+
})
|
665
|
+
|
666
|
+
if (!namespace) {
|
667
|
+
let alert = "No namespace found for id " + namespace_id;
|
668
|
+
winston.warn(alert);
|
669
|
+
res.status(404).send({ success: false, error: alert })
|
670
|
+
}
|
671
|
+
|
595
672
|
let data = {
|
596
|
-
namespace: namespace_id
|
673
|
+
namespace: namespace_id,
|
674
|
+
engine: namespace.engine || default_engine
|
597
675
|
}
|
598
676
|
|
599
677
|
if (req.query.contents_only && (req.query.contents_only === true || req.query.contents_only === 'true')) {
|
@@ -601,7 +679,7 @@ router.delete('/namespace/:id', async (req, res) => {
|
|
601
679
|
openaiService.deleteNamespace(data).then(async (resp) => {
|
602
680
|
winston.debug("delete namespace resp: ", resp.data);
|
603
681
|
|
604
|
-
let deleteResponse = await KB.deleteMany({ id_project:
|
682
|
+
let deleteResponse = await KB.deleteMany({ id_project: project_id, namespace: namespace_id }).catch((err) => {
|
605
683
|
winston.error("deleteMany error: ", err);
|
606
684
|
return res.status(500).send({ success: false, error: err });
|
607
685
|
})
|
@@ -635,7 +713,7 @@ router.delete('/namespace/:id', async (req, res) => {
|
|
635
713
|
openaiService.deleteNamespace(data).then(async (resp) => {
|
636
714
|
winston.debug("delete namespace resp: ", resp.data);
|
637
715
|
|
638
|
-
let deleteResponse = await KB.deleteMany({ id_project:
|
716
|
+
let deleteResponse = await KB.deleteMany({ id_project: project_id, namespace: namespace_id }).catch((err) => {
|
639
717
|
winston.error("deleteMany error: ", err);
|
640
718
|
return res.status(500).send({ success: false, error: err });
|
641
719
|
})
|
@@ -831,7 +909,7 @@ router.post('/', async (req, res) => {
|
|
831
909
|
if (!namespaceIds.includes(body.namespace)) {
|
832
910
|
return res.status(403).send({ success: false, error: "Not allowed. The namespace does not belong to the current project." })
|
833
911
|
}
|
834
|
-
|
912
|
+
|
835
913
|
let quoteManager = req.app.get('quote_manager');
|
836
914
|
let limits = await quoteManager.getPlanLimits(req.project);
|
837
915
|
let kbs_limit = limits.kbs;
|
@@ -848,6 +926,7 @@ router.post('/', async (req, res) => {
|
|
848
926
|
if (total_count > kbs_limit) {
|
849
927
|
return res.status(403).send({ success: false, error: "Cannot exceed the number of resources in the current plan", plan_limit: kbs_limit })
|
850
928
|
}
|
929
|
+
|
851
930
|
let new_kb = {
|
852
931
|
id_project: project_id,
|
853
932
|
name: body.name,
|
@@ -860,6 +939,19 @@ router.post('/', async (req, res) => {
|
|
860
939
|
if (!new_kb.namespace) {
|
861
940
|
new_kb.namespace = project_id;
|
862
941
|
}
|
942
|
+
if (new_kb.type === 'txt') {
|
943
|
+
new_kb.scrape_type = 1;
|
944
|
+
}
|
945
|
+
if (new_kb.type === 'url') {
|
946
|
+
if (!body.scrape_type || body.scrape_type === 2) {
|
947
|
+
new_kb.scrape_type = 2;
|
948
|
+
new_kb.scrape_options = await setDefaultScrapeOptions();
|
949
|
+
} else {
|
950
|
+
new_kb.scrape_type = body.scrape_type;
|
951
|
+
new_kb.scrape_options = body.scrape_options;
|
952
|
+
}
|
953
|
+
}
|
954
|
+
|
863
955
|
winston.debug("adding kb: ", new_kb);
|
864
956
|
|
865
957
|
KB.findOneAndUpdate({ id_project: project_id, type: 'url', source: new_kb.source }, new_kb, { upsert: true, new: true, rawResult: true }, async (err, raw) => {
|
@@ -871,26 +963,37 @@ router.post('/', async (req, res) => {
|
|
871
963
|
|
872
964
|
res.status(200).send(raw);
|
873
965
|
|
966
|
+
let saved_kb = raw.value;
|
874
967
|
let webhook = apiUrl + '/webhook/kb/status?token=' + KB_WEBHOOK_TOKEN;
|
875
968
|
|
876
969
|
let json = {
|
877
|
-
id:
|
878
|
-
type:
|
879
|
-
source:
|
970
|
+
id: saved_kb._id,
|
971
|
+
type: saved_kb.type,
|
972
|
+
source: saved_kb.source,
|
880
973
|
content: "",
|
881
|
-
namespace:
|
974
|
+
namespace: saved_kb.namespace,
|
882
975
|
webhook: webhook
|
883
976
|
}
|
884
977
|
winston.debug("json: ", json);
|
885
978
|
|
886
|
-
if (
|
887
|
-
json.content =
|
979
|
+
if (saved_kb.content) {
|
980
|
+
json.content = saved_kb.content;
|
981
|
+
}
|
982
|
+
if (saved_kb.scrape_type) {
|
983
|
+
json.scrape_type = saved_kb.scrape_type;
|
984
|
+
}
|
985
|
+
if (saved_kb.scrape_options) {
|
986
|
+
json.parameters_scrape_type_4 = saved_kb.scrape_options;
|
888
987
|
}
|
988
|
+
let ns = namespaces.find(n => n.id === body.namespace);
|
989
|
+
json.engine = ns.engine || default_engine;
|
889
990
|
|
890
991
|
let resources = [];
|
891
992
|
|
892
993
|
resources.push(json);
|
893
|
-
|
994
|
+
if (!process.env.NODE_ENV) {
|
995
|
+
scheduleScrape(resources);
|
996
|
+
}
|
894
997
|
|
895
998
|
}
|
896
999
|
})
|
@@ -908,6 +1011,8 @@ router.post('/multi', upload.single('uploadFile'), async (req, res) => {
|
|
908
1011
|
}
|
909
1012
|
|
910
1013
|
let project_id = req.projectid;
|
1014
|
+
let scrape_type = req.body.scrape_type;
|
1015
|
+
let scrape_options = req.body.scrape_options;
|
911
1016
|
|
912
1017
|
let namespace_id = req.query.namespace;
|
913
1018
|
if (!namespace_id) {
|
@@ -956,16 +1061,37 @@ router.post('/multi', upload.single('uploadFile'), async (req, res) => {
|
|
956
1061
|
let webhook = apiUrl + '/webhook/kb/status?token=' + KB_WEBHOOK_TOKEN;
|
957
1062
|
|
958
1063
|
let kbs = [];
|
959
|
-
list.forEach(url => {
|
960
|
-
|
1064
|
+
list.forEach( async (url) => {
|
1065
|
+
let kb = {
|
961
1066
|
id_project: project_id,
|
962
1067
|
name: url,
|
963
1068
|
source: url,
|
964
1069
|
type: 'url',
|
965
1070
|
content: "",
|
966
1071
|
namespace: namespace_id,
|
967
|
-
status: -1
|
968
|
-
|
1072
|
+
status: -1,
|
1073
|
+
scrape_type: scrape_type
|
1074
|
+
}
|
1075
|
+
|
1076
|
+
if (!kb.scrape_type) {
|
1077
|
+
scrape_type = 2;
|
1078
|
+
}
|
1079
|
+
|
1080
|
+
if (scrape_type == 2) {
|
1081
|
+
kb.scrape_options = {
|
1082
|
+
tags_to_extract: ["body"],
|
1083
|
+
unwanted_tags: [],
|
1084
|
+
unwanted_classnames: []
|
1085
|
+
}
|
1086
|
+
} else {
|
1087
|
+
kb.scrape_options = scrape_options;
|
1088
|
+
}
|
1089
|
+
// if (scrape_type === 2) {
|
1090
|
+
// kb.scrape_options = await setDefaultScrapeOptions();
|
1091
|
+
// } else {
|
1092
|
+
// kb.scrape_options = await setCustomScrapeOptions(scrape_options);
|
1093
|
+
// }
|
1094
|
+
kbs.push(kb)
|
969
1095
|
})
|
970
1096
|
|
971
1097
|
let operations = kbs.map(doc => {
|
@@ -979,13 +1105,20 @@ router.post('/multi', upload.single('uploadFile'), async (req, res) => {
|
|
979
1105
|
}
|
980
1106
|
})
|
981
1107
|
|
1108
|
+
console.log("kbs: ", kbs);
|
1109
|
+
|
982
1110
|
saveBulk(operations, kbs, project_id).then((result) => {
|
983
1111
|
|
1112
|
+
let ns = namespaces.find(n => n.id === namespace_id);
|
1113
|
+
let engine = ns.engine || default_engine;
|
1114
|
+
|
984
1115
|
let resources = result.map(({ name, status, __v, createdAt, updatedAt, id_project, ...keepAttrs }) => keepAttrs)
|
985
|
-
resources = resources.map(({ _id, ...rest }) => {
|
986
|
-
return { id: _id, webhook: webhook, ...rest
|
1116
|
+
resources = resources.map(({ _id, scrape_options, ...rest }) => {
|
1117
|
+
return { id: _id, webhook: webhook, parameters_scrape_type_4: scrape_options, engine: engine, ...rest}
|
987
1118
|
});
|
1119
|
+
console.log("resources to be sent to worker: ", resources);
|
988
1120
|
winston.verbose("resources to be sent to worker: ", resources);
|
1121
|
+
|
989
1122
|
scheduleScrape(resources);
|
990
1123
|
res.status(200).send(result);
|
991
1124
|
|
@@ -1085,9 +1218,13 @@ router.post('/csv', upload.single('uploadFile'), async (req, res) => {
|
|
1085
1218
|
})
|
1086
1219
|
|
1087
1220
|
saveBulk(operations, kbs, project_id).then((result) => {
|
1221
|
+
|
1222
|
+
let ns = namespaces.find(n => n.id === namespace_id);
|
1223
|
+
let engine = ns.engine || default_engine;
|
1224
|
+
|
1088
1225
|
let resources = result.map(({ name, status, __v, createdAt, updatedAt, id_project, ...keepAttrs }) => keepAttrs)
|
1089
1226
|
resources = resources.map(({ _id, ...rest}) => {
|
1090
|
-
return { id: _id, webhooh: webhook, ...rest };
|
1227
|
+
return { id: _id, webhooh: webhook, engine: engine, ...rest };
|
1091
1228
|
})
|
1092
1229
|
winston.verbose("resources to be sent to worker: ", resources);
|
1093
1230
|
if (!process.env.NODE_ENV) {
|
@@ -1166,7 +1303,6 @@ router.delete('/:kb_id', async (req, res) => {
|
|
1166
1303
|
let kb_id = req.params.kb_id;
|
1167
1304
|
winston.verbose("delete kb_id " + kb_id);
|
1168
1305
|
|
1169
|
-
|
1170
1306
|
let kb = await KB.findOne({ id_project: project_id, _id: kb_id}).catch((err) => {
|
1171
1307
|
winston.warn("Unable to find kb. Error: ", err);
|
1172
1308
|
return res.status(500).send({ success: false, error: err })
|
@@ -1186,6 +1322,16 @@ router.delete('/:kb_id', async (req, res) => {
|
|
1186
1322
|
data.namespace = project_id;
|
1187
1323
|
}
|
1188
1324
|
|
1325
|
+
let namespaces = await Namespace.find({ id_project: project_id }).catch((err) => {
|
1326
|
+
winston.error("find namespaces error: ", err)
|
1327
|
+
res.status(500).send({ success: false, error: err })
|
1328
|
+
})
|
1329
|
+
|
1330
|
+
let ns = namespaces.find(n => n.id === data.namespace);
|
1331
|
+
data.engine = ns.engine || default_engine;
|
1332
|
+
|
1333
|
+
winston.verbose("/:delete_id data: ", data);
|
1334
|
+
|
1189
1335
|
openaiService.deleteIndex(data).then((resp) => {
|
1190
1336
|
winston.debug("delete resp: ", resp.data);
|
1191
1337
|
if (resp.data.success === true) {
|
@@ -1369,6 +1515,30 @@ async function getKeyFromIntegrations(project_id) {
|
|
1369
1515
|
}
|
1370
1516
|
})
|
1371
1517
|
}
|
1518
|
+
|
1519
|
+
async function setDefaultScrapeOptions() {
|
1520
|
+
return {
|
1521
|
+
tags_to_extract: ["body"],
|
1522
|
+
unwanted_tags: [],
|
1523
|
+
unwanted_classnames: []
|
1524
|
+
}
|
1525
|
+
}
|
1526
|
+
|
1527
|
+
async function setCustomScrapeOptions(options) {
|
1528
|
+
if (!options) {
|
1529
|
+
options = await setDefaultScrapeOptions();
|
1530
|
+
} else {
|
1531
|
+
if (!options.tags_to_extract || options.tags_to_extract.length == 0) {
|
1532
|
+
options.tags_to_extract = ["body"];
|
1533
|
+
}
|
1534
|
+
if (!options.unwanted_tags) {
|
1535
|
+
options.unwanted_tags = [];
|
1536
|
+
}
|
1537
|
+
if (!options.unwanted_classnames) {
|
1538
|
+
options.unwanted_classnames = [];
|
1539
|
+
}
|
1540
|
+
}
|
1541
|
+
}
|
1372
1542
|
/**
|
1373
1543
|
* ****************************************
|
1374
1544
|
* Utils Methods Section - End
|
@@ -1,11 +1,13 @@
|
|
1
1
|
var winston = require('../config/winston');
|
2
2
|
const axios = require("axios").default;
|
3
3
|
require('dotenv').config();
|
4
|
+
const jwt = require("jsonwebtoken")
|
4
5
|
|
5
6
|
let openai_endpoint = process.env.OPENAI_ENDPOINT;
|
6
7
|
let kb_endpoint = process.env.KB_ENDPOINT;
|
7
8
|
let kb_endpoint_train = process.env.KB_ENDPOINT_TRAIN;
|
8
9
|
let kb_endpoint_qa = process.env.KB_ENDPOINT_QA;
|
10
|
+
let secret = process.env.JWT_SECRET_KEY;
|
9
11
|
|
10
12
|
class OpenaiService {
|
11
13
|
|
@@ -162,13 +164,15 @@ class OpenaiService {
|
|
162
164
|
})
|
163
165
|
}
|
164
166
|
|
165
|
-
getContentChunks(namespace_id, content_id) {
|
167
|
+
getContentChunks(namespace_id, content_id, engine) {
|
166
168
|
winston.info("[OPENAI SERVICE] kb endpoint: " + kb_endpoint_train);
|
167
169
|
winston.info(kb_endpoint_train + "/id/" + content_id + "/namespace/" + namespace_id)
|
168
170
|
return new Promise((resolve, reject) => {
|
169
171
|
|
172
|
+
let payload = { engine: engine };
|
173
|
+
let token = jwt.sign(payload, secret);
|
170
174
|
axios({
|
171
|
-
url: kb_endpoint_train + "/id/" + content_id + "/namespace/" + namespace_id,
|
175
|
+
url: kb_endpoint_train + "/id/" + content_id + "/namespace/" + namespace_id + "/" + token,
|
172
176
|
headers: {
|
173
177
|
'Content-Type': 'application/json'
|
174
178
|
},
|
package/test/kbRoute.js
CHANGED
@@ -58,7 +58,6 @@ describe('KbRoute', () => {
|
|
58
58
|
expect(res.body.length).to.equal(1);
|
59
59
|
|
60
60
|
let namespace_id = res.body[0].id;
|
61
|
-
console.log("namespace_id: ", namespace_id);
|
62
61
|
|
63
62
|
let kb = {
|
64
63
|
name: "example_name5",
|
@@ -93,6 +92,128 @@ describe('KbRoute', () => {
|
|
93
92
|
|
94
93
|
})
|
95
94
|
|
95
|
+
it('create-new-text-kb', (done) => {
|
96
|
+
|
97
|
+
var email = "test-signup-" + Date.now() + "@email.com";
|
98
|
+
var pwd = "pwd";
|
99
|
+
|
100
|
+
userService.signup(email, pwd, "Test Firstname", "Test lastname").then(function (savedUser) {
|
101
|
+
projectService.create("test-faqkb-create", savedUser._id).then(function (savedProject) {
|
102
|
+
|
103
|
+
chai.request(server)
|
104
|
+
.get('/' + savedProject._id + '/kb/namespace/all')
|
105
|
+
.auth(email, pwd)
|
106
|
+
.end((err, res) => {
|
107
|
+
|
108
|
+
if (err) { console.error("err: ", err); }
|
109
|
+
if (log) { console.log("get namespaces res.body: ", res.body); }
|
110
|
+
|
111
|
+
res.should.have.status(200);
|
112
|
+
expect(res.body.length).to.equal(1);
|
113
|
+
|
114
|
+
let namespace_id = res.body[0].id;
|
115
|
+
console.log("namespace_id: ", namespace_id);
|
116
|
+
|
117
|
+
let kb = {
|
118
|
+
name: "example_text1",
|
119
|
+
type: "text",
|
120
|
+
source: "example_text1",
|
121
|
+
content: "Example text",
|
122
|
+
namespace: namespace_id
|
123
|
+
}
|
124
|
+
|
125
|
+
chai.request(server)
|
126
|
+
.post('/' + savedProject._id + '/kb')
|
127
|
+
.auth(email, pwd)
|
128
|
+
.send(kb) // can be empty
|
129
|
+
.end((err, res) => {
|
130
|
+
|
131
|
+
if (err) { console.error("err: ", err); }
|
132
|
+
if (log) { console.log("create kb res.body: ", res.body); }
|
133
|
+
console.log("create kb res.body: ", res.body);
|
134
|
+
res.should.have.status(200);
|
135
|
+
res.body.should.be.a('object');
|
136
|
+
expect(res.body.value.id_project).to.equal(res.body.value.namespace)
|
137
|
+
expect(res.body.value.name).to.equal("example_text1")
|
138
|
+
expect(res.body.value.type).to.equal("text")
|
139
|
+
expect(res.body.value.source).to.equal("example_text1")
|
140
|
+
expect(res.body.value.status).to.equal(-1)
|
141
|
+
expect(typeof res.body.value.scrape_type === "undefined").to.be.true;
|
142
|
+
expect(typeof res.body.value.scrape_options === "undefined").to.be.true;
|
143
|
+
|
144
|
+
|
145
|
+
done();
|
146
|
+
})
|
147
|
+
})
|
148
|
+
});
|
149
|
+
});
|
150
|
+
|
151
|
+
})
|
152
|
+
|
153
|
+
it('get-kb-chunks', (done) => {
|
154
|
+
|
155
|
+
var email = "test-signup-" + Date.now() + "@email.com";
|
156
|
+
var pwd = "pwd";
|
157
|
+
|
158
|
+
userService.signup(email, pwd, "Test Firstname", "Test lastname").then(function (savedUser) {
|
159
|
+
projectService.create("test-faqkb-create", savedUser._id).then(function (savedProject) {
|
160
|
+
|
161
|
+
chai.request(server)
|
162
|
+
.get('/' + savedProject._id + '/kb/namespace/all')
|
163
|
+
.auth(email, pwd)
|
164
|
+
.end((err, res) => {
|
165
|
+
|
166
|
+
if (err) { console.error("err: ", err); }
|
167
|
+
if (log) { console.log("get namespaces res.body: ", res.body); }
|
168
|
+
|
169
|
+
res.should.have.status(200);
|
170
|
+
expect(res.body.length).to.equal(1);
|
171
|
+
|
172
|
+
let namespace_id = res.body[0].id;
|
173
|
+
|
174
|
+
let kb = {
|
175
|
+
name: "example_text1",
|
176
|
+
type: "text",
|
177
|
+
source: "example_text1",
|
178
|
+
content: "Example text",
|
179
|
+
namespace: namespace_id
|
180
|
+
}
|
181
|
+
|
182
|
+
chai.request(server)
|
183
|
+
.post('/' + savedProject._id + '/kb')
|
184
|
+
.auth(email, pwd)
|
185
|
+
.send(kb) // can be empty
|
186
|
+
.end((err, res) => {
|
187
|
+
|
188
|
+
if (err) { console.error("err: ", err); }
|
189
|
+
if (log) { console.log("create kb res.body: ", res.body); }
|
190
|
+
console.log("create kb res.body: ", res.body);
|
191
|
+
res.should.have.status(200);
|
192
|
+
res.body.should.be.a('object');
|
193
|
+
|
194
|
+
let content_id = res.body.value._id;
|
195
|
+
|
196
|
+
chai.request(server)
|
197
|
+
.get('/' + savedProject._id + '/kb/namespace/' + namespace_id + '/chunks/' + content_id)
|
198
|
+
.auth(email, pwd)
|
199
|
+
.end((err, res) => {
|
200
|
+
|
201
|
+
if (err) { console.error("err: ", err )};
|
202
|
+
if (log) { console.log("res.body: ", res.body )};
|
203
|
+
|
204
|
+
res.should.have.status(200);
|
205
|
+
//expect(res.body.length).to.equal(1);
|
206
|
+
|
207
|
+
done();
|
208
|
+
})
|
209
|
+
|
210
|
+
})
|
211
|
+
})
|
212
|
+
});
|
213
|
+
});
|
214
|
+
|
215
|
+
})
|
216
|
+
|
96
217
|
it('get-with-queries', (done) => {
|
97
218
|
|
98
219
|
var email = "test-signup-" + Date.now() + "@email.com";
|
@@ -172,14 +293,14 @@ describe('KbRoute', () => {
|
|
172
293
|
if (log) { console.log("create kb3 res.body: ", res.body); }
|
173
294
|
res.should.have.status(200);
|
174
295
|
|
175
|
-
let query = "?status
|
176
|
-
//let query = "";
|
177
|
-
console.log("query: ", query);
|
296
|
+
let query = "?status=-1&type=url&limit=5&page=0&direction=-1&sortField=updatedAt&search=example&namespace=" + namespace_id;
|
297
|
+
//let query = "?namespace=" + namespace_id;
|
178
298
|
|
179
299
|
chai.request(server)
|
180
300
|
.get('/' + savedProject._id + "/kb" + query)
|
181
301
|
.auth(email, pwd)
|
182
302
|
.end((err, res) => {
|
303
|
+
if (err) { console.error("err: ", err)}
|
183
304
|
if (log) { console.log("getall res.body: ", res.body); }
|
184
305
|
res.should.have.status(200);
|
185
306
|
res.body.should.be.a('object');
|
@@ -187,7 +308,7 @@ describe('KbRoute', () => {
|
|
187
308
|
expect(res.body.kbs.length).to.equal(2);
|
188
309
|
expect(res.body.count).to.equal(2);
|
189
310
|
res.body.query.should.be.a('object');
|
190
|
-
expect(res.body.query.status).to.equal(
|
311
|
+
expect(res.body.query.status).to.equal(-1);
|
191
312
|
expect(res.body.query.limit).to.equal(5);
|
192
313
|
expect(res.body.query.page).to.equal(0);
|
193
314
|
expect(res.body.query.direction).to.equal(-1);
|
@@ -255,7 +376,6 @@ describe('KbRoute', () => {
|
|
255
376
|
let namespace_id = "fakenamespaceid";
|
256
377
|
|
257
378
|
let query = "?status=100&type=url&limit=5&page=0&direction=-1&sortField=updatedAt&search=example&namespace=" + namespace_id;
|
258
|
-
console.log("query: ", query);
|
259
379
|
|
260
380
|
chai.request(server)
|
261
381
|
.get('/' + savedProject._id + "/kb" + query)
|
@@ -308,7 +428,6 @@ describe('KbRoute', () => {
|
|
308
428
|
|
309
429
|
if (err) { console.error("err: ", err); }
|
310
430
|
if (log) { console.log("res.body: ", res.body) }
|
311
|
-
console.log("res.body: ", res.body)
|
312
431
|
|
313
432
|
res.should.have.status(200);
|
314
433
|
|
@@ -357,6 +476,7 @@ describe('KbRoute', () => {
|
|
357
476
|
|
358
477
|
}).timeout(10000)
|
359
478
|
|
479
|
+
|
360
480
|
/**
|
361
481
|
* If you try to add content to a namespace that does not belong to the selected project and
|
362
482
|
* the project has at least one namesapce, it returns 403 forbidden.
|
@@ -435,6 +555,7 @@ describe('KbRoute', () => {
|
|
435
555
|
|
436
556
|
if (err) { console.error("err: ", err); }
|
437
557
|
if (log) { console.log("res.body: ", res.body) }
|
558
|
+
console.log("res.body: ", res.body)
|
438
559
|
|
439
560
|
res.should.have.status(200);
|
440
561
|
expect(res.body.length).to.equal(4)
|
@@ -448,6 +569,97 @@ describe('KbRoute', () => {
|
|
448
569
|
|
449
570
|
}).timeout(10000)
|
450
571
|
|
572
|
+
it('add-multiple-urls-with-scrape-option-success-type-4', (done) => {
|
573
|
+
|
574
|
+
var email = "test-signup-" + Date.now() + "@email.com";
|
575
|
+
var pwd = "pwd";
|
576
|
+
|
577
|
+
userService.signup(email, pwd, "Test Firstname", "Test lastname").then(function (savedUser) {
|
578
|
+
projectService.create("test-faqkb-create", savedUser._id).then(function (savedProject) {
|
579
|
+
|
580
|
+
chai.request(server)
|
581
|
+
.get('/' + savedProject._id + '/kb/namespace/all')
|
582
|
+
.auth(email, pwd)
|
583
|
+
.end((err, res) => {
|
584
|
+
|
585
|
+
if (err) { console.error("err: ", err); }
|
586
|
+
if (log) { console.log("res.body: ", res.body) }
|
587
|
+
|
588
|
+
res.should.have.status(200)
|
589
|
+
expect(res.body.length).to.equal(1);
|
590
|
+
|
591
|
+
let namespace_id = res.body[0].id;
|
592
|
+
|
593
|
+
chai.request(server)
|
594
|
+
.post('/' + savedProject._id + '/kb/multi?namespace=' + namespace_id)
|
595
|
+
.auth(email, pwd)
|
596
|
+
.send({ list:["https://gethelp.tiledesk.com/article"], scrape_type: 4, scrape_options: { tags_to_extract: ["article","p"], unwanted_tags:["script","style"], unwanted_classnames:["header","related-articles"]}})
|
597
|
+
.end((err, res) => {
|
598
|
+
|
599
|
+
if (err) { console.error("err: ", err); }
|
600
|
+
if (log) { console.log("res.body: ", res.body) }
|
601
|
+
console.log("res.body: ", res.body)
|
602
|
+
res.should.have.status(200);
|
603
|
+
expect(res.body.length).to.equal(1)
|
604
|
+
expect(res.body[0].scrape_type).to.equal(4)
|
605
|
+
expect(typeof res.body[0].scrape_options === "undefined").to.be.false;
|
606
|
+
expect(res.body[0].scrape_options.tags_to_extract.length).to.equal(2);
|
607
|
+
expect(res.body[0].scrape_options.unwanted_tags.length).to.equal(2);
|
608
|
+
expect(res.body[0].scrape_options.unwanted_classnames.length).to.equal(2);
|
609
|
+
|
610
|
+
done();
|
611
|
+
|
612
|
+
})
|
613
|
+
})
|
614
|
+
});
|
615
|
+
});
|
616
|
+
|
617
|
+
}).timeout(10000)
|
618
|
+
|
619
|
+
it('add-multiple-urls-with-scrape-option-success-type-3', (done) => {
|
620
|
+
|
621
|
+
var email = "test-signup-" + Date.now() + "@email.com";
|
622
|
+
var pwd = "pwd";
|
623
|
+
|
624
|
+
userService.signup(email, pwd, "Test Firstname", "Test lastname").then(function (savedUser) {
|
625
|
+
projectService.create("test-faqkb-create", savedUser._id).then(function (savedProject) {
|
626
|
+
|
627
|
+
chai.request(server)
|
628
|
+
.get('/' + savedProject._id + '/kb/namespace/all')
|
629
|
+
.auth(email, pwd)
|
630
|
+
.end((err, res) => {
|
631
|
+
|
632
|
+
if (err) { console.error("err: ", err); }
|
633
|
+
if (log) { console.log("res.body: ", res.body) }
|
634
|
+
|
635
|
+
res.should.have.status(200)
|
636
|
+
expect(res.body.length).to.equal(1);
|
637
|
+
|
638
|
+
let namespace_id = res.body[0].id;
|
639
|
+
|
640
|
+
chai.request(server)
|
641
|
+
.post('/' + savedProject._id + '/kb/multi?namespace=' + namespace_id)
|
642
|
+
.auth(email, pwd)
|
643
|
+
.send({ list:["https://gethelp.tiledesk.com/article"], scrape_type: 3 })
|
644
|
+
.end((err, res) => {
|
645
|
+
|
646
|
+
if (err) { console.error("err: ", err); }
|
647
|
+
if (log) { console.log("res.body: ", res.body) }
|
648
|
+
console.log("res.body: ", res.body)
|
649
|
+
res.should.have.status(200);
|
650
|
+
expect(res.body.length).to.equal(1)
|
651
|
+
expect(res.body[0].scrape_type).to.equal(3)
|
652
|
+
expect(typeof res.body[0].scrape_options === "undefined").to.be.true;
|
653
|
+
|
654
|
+
done();
|
655
|
+
|
656
|
+
})
|
657
|
+
})
|
658
|
+
});
|
659
|
+
});
|
660
|
+
|
661
|
+
}).timeout(10000)
|
662
|
+
|
451
663
|
it('expand-sitemap', (done) => {
|
452
664
|
|
453
665
|
var email = "test-signup-" + Date.now() + "@email.com";
|
@@ -1098,41 +1310,41 @@ describe('KbRoute', () => {
|
|
1098
1310
|
// }).timeout(10000)
|
1099
1311
|
|
1100
1312
|
// Ask KB
|
1101
|
-
|
1313
|
+
it('askkb-key-from-env', (done) => {
|
1102
1314
|
|
1103
|
-
|
1104
|
-
|
1315
|
+
var email = "test-signup-" + Date.now() + "@email.com";
|
1316
|
+
var pwd = "pwd";
|
1105
1317
|
|
1106
|
-
|
1107
|
-
|
1318
|
+
userService.signup(email, pwd, "Test Firstname", "Test Lastname").then((savedUser) => {
|
1319
|
+
projectService.create("test-kb-qa", savedUser._id).then((savedProject) => {
|
1108
1320
|
|
1109
|
-
|
1110
|
-
|
1111
|
-
|
1112
|
-
|
1321
|
+
chai.request(server)
|
1322
|
+
.get('/' + savedProject._id + '/kb/namespace/all')
|
1323
|
+
.auth(email, pwd)
|
1324
|
+
.end((err, res) => {
|
1113
1325
|
|
1114
|
-
|
1115
|
-
|
1116
|
-
|
1117
|
-
// console.log("namespace created..")
|
1326
|
+
if (err) { console.error("err: ", err); }
|
1327
|
+
if (log) { console.log("get all namespaces res.body: ", res.body); }
|
1118
1328
|
|
1119
|
-
|
1120
|
-
// .post('/' + savedProject._id + "/kb/qa")
|
1121
|
-
// .auth(email, pwd)
|
1122
|
-
// .send({ model: "gpt-4o", namespace: savedProject._id, question: "sample question" })
|
1123
|
-
// .end((err, res) => {
|
1329
|
+
console.log("namespace created..")
|
1124
1330
|
|
1125
|
-
|
1126
|
-
|
1127
|
-
|
1128
|
-
|
1129
|
-
|
1331
|
+
chai.request(server)
|
1332
|
+
.post('/' + savedProject._id + "/kb/qa")
|
1333
|
+
.auth(email, pwd)
|
1334
|
+
.send({ model: "gpt-4o", namespace: savedProject._id, question: "sample question", advancedPrompt: true, system_context: "You are a robot coming from future" })
|
1335
|
+
.end((err, res) => {
|
1130
1336
|
|
1337
|
+
if (err) { console.error("err: ", err) };
|
1338
|
+
if (log) { console.log("res.body: ", res.body) };
|
1339
|
+
console.log("res.body: ", res.body)
|
1340
|
+
done();
|
1341
|
+
})
|
1131
1342
|
|
1132
|
-
|
1133
|
-
|
1134
|
-
|
1135
|
-
|
1343
|
+
|
1344
|
+
})
|
1345
|
+
})
|
1346
|
+
})
|
1347
|
+
}).timeout(10000)
|
1136
1348
|
|
1137
1349
|
|
1138
1350
|
it('webhook', (done) => {
|
@@ -1215,7 +1427,7 @@ describe('KbRoute', () => {
|
|
1215
1427
|
* Get all namespaces of a project.
|
1216
1428
|
* If there isn't namespaces for a project_id, the default namespace is created and returned.
|
1217
1429
|
*/
|
1218
|
-
it('get-namespaces', (done) => {
|
1430
|
+
it('get-namespaces-1', (done) => {
|
1219
1431
|
|
1220
1432
|
var email = "test-signup-" + Date.now() + "@email.com";
|
1221
1433
|
var pwd = "pwd";
|
@@ -1238,6 +1450,8 @@ describe('KbRoute', () => {
|
|
1238
1450
|
//expect(res.body[0]._id).to.equal(undefined);
|
1239
1451
|
expect(res.body[0].id).to.equal(savedProject._id.toString());
|
1240
1452
|
expect(res.body[0].name).to.equal("Default");
|
1453
|
+
should.exist(res.body[0].engine)
|
1454
|
+
expect(res.body[0].engine.name).to.equal('pinecone')
|
1241
1455
|
|
1242
1456
|
done();
|
1243
1457
|
|
@@ -1318,6 +1532,76 @@ describe('KbRoute', () => {
|
|
1318
1532
|
});
|
1319
1533
|
})
|
1320
1534
|
|
1535
|
+
it('create-namespaces-with-engine', (done) => {
|
1536
|
+
|
1537
|
+
var email = "test-signup-" + Date.now() + "@email.com";
|
1538
|
+
var pwd = "pwd";
|
1539
|
+
|
1540
|
+
userService.signup(email, pwd, "Test Firstname", "Test lastname").then(function (savedUser) {
|
1541
|
+
projectService.create("test-faqkb-create", savedUser._id).then(function (savedProject) {
|
1542
|
+
|
1543
|
+
// Get all namespaces. Create default namespace and return.
|
1544
|
+
chai.request(server)
|
1545
|
+
.get('/' + savedProject._id + '/kb/namespace/all')
|
1546
|
+
.auth(email, pwd)
|
1547
|
+
.end((err, res) => {
|
1548
|
+
|
1549
|
+
if (err) { console.error("err: ", err); }
|
1550
|
+
if (log) { console.log("get all namespaces res.body: ", res.body); }
|
1551
|
+
|
1552
|
+
res.should.have.status(200);
|
1553
|
+
res.body.should.be.a('array');
|
1554
|
+
expect(res.body.length).to.equal(1);
|
1555
|
+
should.not.exist(res.body[0]._id);
|
1556
|
+
expect(res.body[0].id).to.equal(savedProject._id.toString());
|
1557
|
+
expect(res.body[0].name).to.equal("Default");
|
1558
|
+
should.exist(res.body[0].engine)
|
1559
|
+
expect(res.body[0].engine.name).to.equal('pinecone');
|
1560
|
+
expect(res.body[0].engine.type).to.equal('pod');
|
1561
|
+
|
1562
|
+
// Create another namespace
|
1563
|
+
chai.request(server)
|
1564
|
+
.post('/' + savedProject._id + '/kb/namespace')
|
1565
|
+
.auth(email, pwd)
|
1566
|
+
.send({ name: "MyCustomNamespace" })
|
1567
|
+
.end((err, res) => {
|
1568
|
+
|
1569
|
+
if (err) { console.error("err: ", err) }
|
1570
|
+
if (log) { console.log("create new namespace res.body: ", res.body) }
|
1571
|
+
|
1572
|
+
res.should.have.status(200);
|
1573
|
+
res.body.should.be.a('object');
|
1574
|
+
should.not.exist(res.body._id)
|
1575
|
+
should.exist(res.body.id)
|
1576
|
+
expect(res.body.name).to.equal('MyCustomNamespace');
|
1577
|
+
should.exist(res.body.engine)
|
1578
|
+
expect(res.body.engine.name).to.equal('pinecone');
|
1579
|
+
expect(res.body.engine.type).to.equal('pod');
|
1580
|
+
|
1581
|
+
// Get again all namespace. A new default namespace should not be created.
|
1582
|
+
chai.request(server)
|
1583
|
+
.get('/' + savedProject._id + '/kb/namespace/all')
|
1584
|
+
.auth(email, pwd)
|
1585
|
+
.end((err, res) => {
|
1586
|
+
|
1587
|
+
if (err) { console.error("err: ", err); }
|
1588
|
+
if (log) { console.log("get all namespaces res.body: ", res.body); }
|
1589
|
+
|
1590
|
+
res.should.have.status(200);
|
1591
|
+
res.body.should.be.a('array');
|
1592
|
+
expect(res.body.length).to.equal(2);
|
1593
|
+
should.not.exist(res.body[0]._id);
|
1594
|
+
should.not.exist(res.body[1]._id);
|
1595
|
+
should.exist(res.body[0].id);
|
1596
|
+
should.exist(res.body[1].id);
|
1597
|
+
|
1598
|
+
done();
|
1599
|
+
})
|
1600
|
+
})
|
1601
|
+
})
|
1602
|
+
});
|
1603
|
+
});
|
1604
|
+
})
|
1321
1605
|
|
1322
1606
|
/**
|
1323
1607
|
* Update namespaces
|
@@ -1346,7 +1630,6 @@ describe('KbRoute', () => {
|
|
1346
1630
|
expect(res.body[0].name).to.equal("Default");
|
1347
1631
|
|
1348
1632
|
let namespace_id = res.body[0].id;
|
1349
|
-
console.log("namespace_id: ", namespace_id);
|
1350
1633
|
|
1351
1634
|
let new_settings = {
|
1352
1635
|
model: 'gpt-4o',
|
@@ -1411,7 +1694,6 @@ describe('KbRoute', () => {
|
|
1411
1694
|
expect(res.body[0].name).to.equal("Default");
|
1412
1695
|
|
1413
1696
|
let namespace_id = res.body[0].id;
|
1414
|
-
console.log("namespace_id: ", namespace_id);
|
1415
1697
|
|
1416
1698
|
// Update namespace
|
1417
1699
|
chai.request(server)
|