@tiledesk/tiledesk-server 2.10.36 → 2.10.37
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/CHANGELOG.md +6 -0
- package/models/kb_setting.js +8 -0
- package/package.json +2 -2
- package/routes/kb.js +14 -16
- package/routes/kbsettings.js +4 -4
- package/routes/openai.js +2 -2
- package/routes/webhook.js +134 -1
- package/services/QuoteManager.js +37 -10
- package/services/aiReindexService.js +151 -0
- package/services/{openaiService.js → aiService.js} +3 -3
- package/services/requestService.js +449 -435
- package/test/kbRoute.js +74 -2
package/CHANGELOG.md
CHANGED
@@ -5,6 +5,12 @@
|
|
5
5
|
🚀 IN PRODUCTION 🚀
|
6
6
|
(https://www.npmjs.com/package/@tiledesk/tiledesk-server/v/2.3.77)
|
7
7
|
|
8
|
+
# 2.10.37
|
9
|
+
- added voice-duration quota
|
10
|
+
- added webhook endpoint for auto reindexing
|
11
|
+
- updated vxml-connector to 0.1.70
|
12
|
+
|
13
|
+
|
8
14
|
# 2.10.36
|
9
15
|
- updated tybot-connector to 0.2.138
|
10
16
|
|
package/models/kb_setting.js
CHANGED
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.10.
|
4
|
+
"version": "2.10.37",
|
5
5
|
"scripts": {
|
6
6
|
"start": "node ./bin/www",
|
7
7
|
"pretest": "mongodb-runner start",
|
@@ -52,7 +52,7 @@
|
|
52
52
|
"@tiledesk/tiledesk-whatsapp-connector": "^0.1.75",
|
53
53
|
"@tiledesk/tiledesk-whatsapp-jobworker": "^0.0.10",
|
54
54
|
"@tiledesk/tiledesk-sms-connector": "^0.1.11",
|
55
|
-
"@tiledesk/tiledesk-vxml-connector": "^0.1.
|
55
|
+
"@tiledesk/tiledesk-vxml-connector": "^0.1.70",
|
56
56
|
"@tiledesk/tiledesk-voice-twilio-connector": "^0.1.12",
|
57
57
|
"@tiledesk/tiledesk-multi-worker": "^0.1.6",
|
58
58
|
"amqplib": "^0.5.5",
|
package/routes/kb.js
CHANGED
@@ -6,7 +6,7 @@ var router = express.Router();
|
|
6
6
|
var winston = require('../config/winston');
|
7
7
|
var multer = require('multer')
|
8
8
|
var upload = multer()
|
9
|
-
const
|
9
|
+
const aiService = require('../services/aiService');
|
10
10
|
const JobManager = require('../utils/jobs-worker-queue-manager/JobManagerV2');
|
11
11
|
const { Scheduler } = require('../services/Scheduler');
|
12
12
|
var configGlobal = require('../config/global');
|
@@ -18,7 +18,6 @@ let Integration = require('../models/integrations');
|
|
18
18
|
var parsecsv = require("fast-csv");
|
19
19
|
|
20
20
|
const { MODELS_MULTIPLIER } = require('../utils/aiUtils');
|
21
|
-
const { body } = require('express-validator');
|
22
21
|
|
23
22
|
const AMQP_MANAGER_URL = process.env.AMQP_MANAGER_URL;
|
24
23
|
const JOB_TOPIC_EXCHANGE = process.env.JOB_TOPIC_EXCHANGE_TRAIN || 'tiledesk-trainer';
|
@@ -190,7 +189,7 @@ router.post('/scrape/status', async (req, res) => {
|
|
190
189
|
let ns = namespaces.find(n => n.id === data.namespace);
|
191
190
|
data.engine = ns.engine || default_engine;
|
192
191
|
|
193
|
-
|
192
|
+
aiService.scrapeStatus(data).then(async (response) => {
|
194
193
|
|
195
194
|
winston.debug("scrapeStatus response.data: ", response.data);
|
196
195
|
|
@@ -294,7 +293,7 @@ router.post('/qa', async (req, res) => {
|
|
294
293
|
return res.status(200).send({ success: true, message: "Question skipped in test environment"});
|
295
294
|
}
|
296
295
|
|
297
|
-
|
296
|
+
aiService.askNamespace(data).then((resp) => {
|
298
297
|
winston.debug("qa resp: ", resp.data);
|
299
298
|
let answer = resp.data;
|
300
299
|
|
@@ -353,7 +352,7 @@ router.delete('/delete', async (req, res) => {
|
|
353
352
|
let ns = namespaces.find(n => n.id === data.namespace);
|
354
353
|
data.engine = ns.engine || default_engine;
|
355
354
|
|
356
|
-
|
355
|
+
aiService.deleteIndex(data).then((resp) => {
|
357
356
|
winston.debug("delete resp: ", resp.data);
|
358
357
|
res.status(200).send(resp.data);
|
359
358
|
}).catch((err) => {
|
@@ -392,7 +391,7 @@ router.delete('/deleteall', async (req, res) => {
|
|
392
391
|
|
393
392
|
winston.verbose("/deleteall data: ", data);
|
394
393
|
|
395
|
-
|
394
|
+
aiService.deleteNamespace(data).then((resp) => {
|
396
395
|
winston.debug("delete namespace resp: ", resp.data);
|
397
396
|
res.status(200).send(resp.data);
|
398
397
|
}).catch((err) => {
|
@@ -497,7 +496,7 @@ router.get('/namespace/:id/chunks/:content_id', async (req, res) => {
|
|
497
496
|
return res.status(200).send({ success: true, message: "Get chunks skipped in test environment"});
|
498
497
|
}
|
499
498
|
|
500
|
-
|
499
|
+
aiService.getContentChunks(namespace_id, content_id, engine).then((resp) => {
|
501
500
|
let chunks = resp.data;
|
502
501
|
winston.debug("chunks for content " + content_id);
|
503
502
|
winston.debug("chunks found ", chunks);
|
@@ -659,7 +658,7 @@ router.delete('/namespace/:id', async (req, res) => {
|
|
659
658
|
|
660
659
|
if (req.query.contents_only && (req.query.contents_only === true || req.query.contents_only === 'true')) {
|
661
660
|
|
662
|
-
|
661
|
+
aiService.deleteNamespace(data).then(async (resp) => {
|
663
662
|
winston.debug("delete namespace resp: ", resp.data);
|
664
663
|
|
665
664
|
let deleteResponse = await KB.deleteMany({ id_project: project_id, namespace: namespace_id }).catch((err) => {
|
@@ -693,7 +692,7 @@ router.delete('/namespace/:id', async (req, res) => {
|
|
693
692
|
return res.status(403).send({ success: false, error: "Default namespace cannot be deleted" });
|
694
693
|
}
|
695
694
|
|
696
|
-
|
695
|
+
aiService.deleteNamespace(data).then(async (resp) => {
|
697
696
|
winston.debug("delete namespace resp: ", resp.data);
|
698
697
|
|
699
698
|
let deleteResponse = await KB.deleteMany({ id_project: project_id, namespace: namespace_id }).catch((err) => {
|
@@ -926,6 +925,7 @@ router.post('/', async (req, res) => {
|
|
926
925
|
new_kb.scrape_type = 1;
|
927
926
|
}
|
928
927
|
if (new_kb.type === 'url') {
|
928
|
+
new_kb.refresh = body.refresh;
|
929
929
|
if (!body.scrape_type || body.scrape_type === 2) {
|
930
930
|
new_kb.scrape_type = 2;
|
931
931
|
new_kb.scrape_options = await setDefaultScrapeOptions();
|
@@ -999,6 +999,7 @@ router.post('/multi', upload.single('uploadFile'), async (req, res) => {
|
|
999
999
|
let project_id = req.projectid;
|
1000
1000
|
let scrape_type = req.body.scrape_type;
|
1001
1001
|
let scrape_options = req.body.scrape_options;
|
1002
|
+
let refresh_rate = req.body.refresh_rate;
|
1002
1003
|
|
1003
1004
|
let namespace_id = req.query.namespace;
|
1004
1005
|
if (!namespace_id) {
|
@@ -1056,7 +1057,8 @@ router.post('/multi', upload.single('uploadFile'), async (req, res) => {
|
|
1056
1057
|
content: "",
|
1057
1058
|
namespace: namespace_id,
|
1058
1059
|
status: -1,
|
1059
|
-
scrape_type: scrape_type
|
1060
|
+
scrape_type: scrape_type,
|
1061
|
+
refresh_rate: refresh_rate
|
1060
1062
|
}
|
1061
1063
|
|
1062
1064
|
if (!kb.scrape_type) {
|
@@ -1316,7 +1318,7 @@ router.delete('/:kb_id', async (req, res) => {
|
|
1316
1318
|
|
1317
1319
|
winston.verbose("/:delete_id data: ", data);
|
1318
1320
|
|
1319
|
-
|
1321
|
+
aiService.deleteIndex(data).then((resp) => {
|
1320
1322
|
winston.debug("delete resp: ", resp.data);
|
1321
1323
|
if (resp.data.success === true) {
|
1322
1324
|
KB.findByIdAndDelete(kb_id, (err, deletedKb) => {
|
@@ -1432,9 +1434,6 @@ async function updateStatus(id, status) {
|
|
1432
1434
|
|
1433
1435
|
async function scheduleScrape(resources) {
|
1434
1436
|
|
1435
|
-
// let data = {
|
1436
|
-
// resources: resources
|
1437
|
-
// }
|
1438
1437
|
let scheduler = new Scheduler({ jobManager: jobManager });
|
1439
1438
|
|
1440
1439
|
resources.forEach(r => {
|
@@ -1451,7 +1450,6 @@ async function scheduleScrape(resources) {
|
|
1451
1450
|
});
|
1452
1451
|
})
|
1453
1452
|
|
1454
|
-
|
1455
1453
|
return true;
|
1456
1454
|
}
|
1457
1455
|
|
@@ -1470,7 +1468,7 @@ async function startScrape(data) {
|
|
1470
1468
|
winston.verbose("status of kb " + data.id + " updated: " + status_updated);
|
1471
1469
|
|
1472
1470
|
return new Promise((resolve, reject) => {
|
1473
|
-
|
1471
|
+
aiService.singleScrape(data).then(async (resp) => {
|
1474
1472
|
winston.debug("singleScrape resp: ", resp.data);
|
1475
1473
|
let status_updated = await updateStatus(data.id, 300);
|
1476
1474
|
winston.verbose("status of kb " + data.id + " updated: " + status_updated);
|
package/routes/kbsettings.js
CHANGED
@@ -4,7 +4,7 @@ var { KBSettings } = require('../models/kb_setting');
|
|
4
4
|
// var KB = require('../models/kb_setting')
|
5
5
|
var router = express.Router();
|
6
6
|
var winston = require('../config/winston');
|
7
|
-
const
|
7
|
+
const aiService = require('../services/aiService');
|
8
8
|
|
9
9
|
router.get('/', async (req, res) => {
|
10
10
|
let project_id = req.projectid;
|
@@ -105,7 +105,7 @@ router.post('/qa', async (req, res) => {
|
|
105
105
|
let data = req.body;
|
106
106
|
winston.debug("/qa data: ", data);
|
107
107
|
|
108
|
-
|
108
|
+
aiService.ask(data).then((resp) => {
|
109
109
|
winston.debug("qa resp: ", resp.data);
|
110
110
|
res.status(200).send(resp.data);
|
111
111
|
}).catch((err) => {
|
@@ -121,7 +121,7 @@ router.post('/startscrape', async (req, res) => {
|
|
121
121
|
let data = req.body;
|
122
122
|
winston.debug("/startscrape data: ", data);
|
123
123
|
|
124
|
-
|
124
|
+
aiService.startScrape(data).then((resp) => {
|
125
125
|
winston.debug("startScrape resp: ", resp.data);
|
126
126
|
res.status(200).send(resp.data);
|
127
127
|
}).catch((err) => {
|
@@ -143,7 +143,7 @@ router.post('/checkstatus', async (req, res) => {
|
|
143
143
|
url_list: [ req.body.full_url ]
|
144
144
|
}
|
145
145
|
|
146
|
-
|
146
|
+
aiService.checkStatus(data).then((resp) => {
|
147
147
|
winston.debug("checkStatus resp: ", resp);
|
148
148
|
winston.debug("checkStatus resp: ", resp.data);
|
149
149
|
winston.debug("checkStatus resp: ", resp.data[full_url]);
|
package/routes/openai.js
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
var express = require('express');
|
2
2
|
var router = express.Router();
|
3
3
|
var { KBSettings } = require('../models/kb_setting');
|
4
|
-
var
|
4
|
+
var aiService = require('../services/aiService');
|
5
5
|
var winston = require('../config/winston');
|
6
6
|
const { QuoteManager } = require('../services/QuoteManager');
|
7
7
|
const { MODELS_MULTIPLIER } = require('../utils/aiUtils');
|
@@ -70,7 +70,7 @@ router.post('/', async (req, res) => {
|
|
70
70
|
winston.info("No multiplier found for AI model")
|
71
71
|
}
|
72
72
|
|
73
|
-
|
73
|
+
aiService.completions(json, gptkey).then(async (response) => {
|
74
74
|
let data = { createdAt: new Date(), tokens: response.data.usage.total_tokens, multiplier: multiplier }
|
75
75
|
if (usePublicKey === true) {
|
76
76
|
let incremented_key = await quoteManager.incrementTokenCount(req.project, data);
|
package/routes/webhook.js
CHANGED
@@ -1,9 +1,124 @@
|
|
1
1
|
var express = require('express');
|
2
2
|
var router = express.Router();
|
3
|
-
var { KB } = require('../models/kb_setting');
|
3
|
+
var { KB, Namespace } = require('../models/kb_setting');
|
4
4
|
var winston = require('../config/winston');
|
5
|
+
const JobManager = require('../utils/jobs-worker-queue-manager/JobManagerV2');
|
6
|
+
const { Scheduler } = require('../services/Scheduler');
|
7
|
+
const { AiReindexService } = require('../services/aiReindexService');
|
5
8
|
|
6
9
|
const KB_WEBHOOK_TOKEN = process.env.KB_WEBHOOK_TOKEN || 'kbcustomtoken';
|
10
|
+
const AMQP_MANAGER_URL = process.env.AMQP_MANAGER_URL;
|
11
|
+
const JOB_TOPIC_EXCHANGE = process.env.JOB_TOPIC_EXCHANGE_TRAIN || 'tiledesk-trainer';
|
12
|
+
|
13
|
+
let jobManager = new JobManager(AMQP_MANAGER_URL, {
|
14
|
+
debug: false,
|
15
|
+
topic: JOB_TOPIC_EXCHANGE,
|
16
|
+
exchange: JOB_TOPIC_EXCHANGE
|
17
|
+
})
|
18
|
+
|
19
|
+
jobManager.connectAndStartPublisher((status, error) => {
|
20
|
+
if (error) {
|
21
|
+
winston.error("connectAndStartPublisher error: ", error);
|
22
|
+
} else {
|
23
|
+
winston.info("KbRoute - ConnectPublisher done with status: ", status);
|
24
|
+
}
|
25
|
+
})
|
26
|
+
|
27
|
+
let default_engine = {
|
28
|
+
name: "pinecone",
|
29
|
+
type: process.env.PINECONE_TYPE,
|
30
|
+
apikey: "",
|
31
|
+
vector_size: 1536,
|
32
|
+
index_name: process.env.PINECONE_INDEX
|
33
|
+
}
|
34
|
+
|
35
|
+
router.post('/kb/reindex', async (req, res) => {
|
36
|
+
|
37
|
+
winston.verbose("/kb/reindex webhook called")
|
38
|
+
winston.debug("(webhook) req.body: ", req.body);
|
39
|
+
|
40
|
+
if (!req.headers['x-auth-token']) {
|
41
|
+
winston.error("(webhook) Unauthorized: A x-auth-token must be provided")
|
42
|
+
return res.status(401).send({ success: false, error: "Unauthorized", message: "A x-auth-token must be provided" })
|
43
|
+
}
|
44
|
+
|
45
|
+
if (req.headers['x-auth-token'] != KB_WEBHOOK_TOKEN) {
|
46
|
+
winston.error("(webhook) Unauthorized: You don't have the authorization to accomplish this operation")
|
47
|
+
return res.status(401).send({ success: false, error: "Unauthorized", message: "You don't have the authorization to accomplish this operation" });
|
48
|
+
}
|
49
|
+
|
50
|
+
let content_id = req.body.content_id;
|
51
|
+
|
52
|
+
let kb = await KB.findById(content_id).catch( async (err) => {
|
53
|
+
winston.error("(webhook) Error getting kb content: ", err);
|
54
|
+
return res.status(500).send({ success: false, error: "Error getting content with id " + content_id });
|
55
|
+
})
|
56
|
+
|
57
|
+
if (!kb) {
|
58
|
+
winston.warn("(webhook) Kb content not found with id " + content_id + ". Deleting scheduler...");
|
59
|
+
|
60
|
+
// Assuming the content has been deleted. The scheduler should be stopped and deleted.
|
61
|
+
res.status(200).send({ success: true, message: "Content no longer exists. Deleting scheduler..." })
|
62
|
+
|
63
|
+
setTimeout( async () => {
|
64
|
+
let aiReindexService = new AiReindexService();
|
65
|
+
let deleteResponse = await aiReindexService.delete(content_id).catch((err) => {
|
66
|
+
winston.error("(webhook) Error deleting scheduler ", err);
|
67
|
+
winston.error("(webhook) Error deleting scheduler " + err);
|
68
|
+
return;
|
69
|
+
});
|
70
|
+
winston.verbose("(webhook) delete response: ", deleteResponse);
|
71
|
+
return;
|
72
|
+
}, 10000);
|
73
|
+
|
74
|
+
} else {
|
75
|
+
|
76
|
+
let json = {
|
77
|
+
id: kb._id,
|
78
|
+
type: kb.type,
|
79
|
+
source: kb.source,
|
80
|
+
content: "",
|
81
|
+
namespace: kb.namespace,
|
82
|
+
refresh_rate: kb.refresh_rate,
|
83
|
+
last_refresh: kb.last_refresh
|
84
|
+
}
|
85
|
+
|
86
|
+
if (kb.scrape_type) {
|
87
|
+
json.scrape_type = kb.scrape_type
|
88
|
+
}
|
89
|
+
|
90
|
+
if (kb.scrape_options) {
|
91
|
+
json.parameters_scrape_type_4 = {
|
92
|
+
tags_to_extract: kb.scrape_options.tags_to_extract,
|
93
|
+
unwanted_tags: kb.scrape_options.unwanted_tags,
|
94
|
+
unwanted_classnames: kb.scrape_options.unwanted_classnames
|
95
|
+
}
|
96
|
+
}
|
97
|
+
|
98
|
+
let namespace = await Namespace.findOne({ id: kb.namespace }).catch((err) => {
|
99
|
+
winston.error("(webhook) Error getting namespace ", err)
|
100
|
+
return res.status(500).send({ success: false, error: err })
|
101
|
+
})
|
102
|
+
|
103
|
+
if (!namespace) {
|
104
|
+
winston.warn("(webhook) Namespace not found with id " + kb.namespace);
|
105
|
+
return res.status(500).send({ success: false, error: err })
|
106
|
+
}
|
107
|
+
|
108
|
+
json.engine = namespace.engine || default_engine;
|
109
|
+
|
110
|
+
let resources = [];
|
111
|
+
resources.push(json);
|
112
|
+
|
113
|
+
if (process.env.NODE_ENV !== 'test') {
|
114
|
+
scheduleScrape(resources);
|
115
|
+
}
|
116
|
+
|
117
|
+
res.status(200).send({ success: true, message: "Content queued for reindexing" });
|
118
|
+
|
119
|
+
}
|
120
|
+
})
|
121
|
+
|
7
122
|
|
8
123
|
router.post('/kb/status', async (req, res) => {
|
9
124
|
|
@@ -52,4 +167,22 @@ router.post('/kb/status', async (req, res) => {
|
|
52
167
|
|
53
168
|
})
|
54
169
|
|
170
|
+
async function scheduleScrape(resources) {
|
171
|
+
|
172
|
+
let scheduler = new Scheduler({ jobManager: jobManager });
|
173
|
+
|
174
|
+
resources.forEach(r => {
|
175
|
+
winston.debug("(Webhook) Schedule job with following data: ", r);
|
176
|
+
scheduler.trainSchedule(r, async (err, result) => {
|
177
|
+
if (err) {
|
178
|
+
winston.error("Scheduling error: ", err);
|
179
|
+
} else {
|
180
|
+
winston.info("Scheduling result: ", result);
|
181
|
+
}
|
182
|
+
});
|
183
|
+
})
|
184
|
+
|
185
|
+
return true;
|
186
|
+
}
|
187
|
+
|
55
188
|
module.exports = router;
|
package/services/QuoteManager.js
CHANGED
@@ -16,15 +16,15 @@ const emailEvent = require('../event/emailEvent');
|
|
16
16
|
|
17
17
|
|
18
18
|
const PLANS_LIST = {
|
19
|
-
FREE_TRIAL: { requests: 200, messages: 0, tokens: 100000,
|
20
|
-
SANDBOX: { requests: 200, messages: 0, tokens: 100000,
|
21
|
-
BASIC: { requests: 800, messages: 0, tokens: 2000000,
|
22
|
-
PREMIUM: { requests: 3000, messages: 0, tokens: 5000000,
|
23
|
-
TEAM: { requests: 5000, messages: 0, tokens: 10000000,
|
24
|
-
CUSTOM: { requests: 5000, messages: 0, tokens: 10000000,
|
19
|
+
FREE_TRIAL: { requests: 200, messages: 0, tokens: 100000, voice_duration: 0, email: 200, chatbots: 20, namespace: 3, kbs: 50 }, // same as PREMIUM
|
20
|
+
SANDBOX: { requests: 200, messages: 0, tokens: 100000, voice_duration: 0, email: 200, chatbots: 2, namespace: 1, kbs: 50 },
|
21
|
+
BASIC: { requests: 800, messages: 0, tokens: 2000000, voice_duration: 0, email: 200, chatbots: 5, namespace: 1, kbs: 150 },
|
22
|
+
PREMIUM: { requests: 3000, messages: 0, tokens: 5000000, voice_duration: 0, email: 200, chatbots: 20, namespace: 3, kbs: 300 },
|
23
|
+
TEAM: { requests: 5000, messages: 0, tokens: 10000000, voice_duration: 0, email: 200, chatbots: 50, namespace: 10, kbs: 1000 },
|
24
|
+
CUSTOM: { requests: 5000, messages: 0, tokens: 10000000, voice_duration: 120000, email: 200, chatbots: 50, namespace: 10, kbs: 1000 },
|
25
25
|
}
|
26
26
|
|
27
|
-
const typesList = ['requests', 'messages', 'email', 'tokens', 'chatbots', 'kbs']
|
27
|
+
const typesList = ['requests', 'messages', 'email', 'tokens', 'voice_duration', 'chatbots', 'kbs']
|
28
28
|
|
29
29
|
let quotes_enabled = true;
|
30
30
|
|
@@ -95,6 +95,25 @@ class QuoteManager {
|
|
95
95
|
this.sendEmailIfQuotaExceeded(project, data, 'tokens', key);
|
96
96
|
return key;
|
97
97
|
}
|
98
|
+
|
99
|
+
async incrementVoiceDurationCount(project, request) {
|
100
|
+
|
101
|
+
this.project = project;
|
102
|
+
let key = await this.generateKey(request, 'voice_duration');
|
103
|
+
winston.verbose("[QuoteManager] incrementVoiceDurationCount key: " + key);
|
104
|
+
|
105
|
+
if (quotes_enabled === false) {
|
106
|
+
winston.debug("QUOTES DISABLED - incrementVoiceDurationCount")
|
107
|
+
return key;
|
108
|
+
}
|
109
|
+
|
110
|
+
if (request?.duration) {
|
111
|
+
let duration = Math.round(request.duration / 1000); // from ms to s
|
112
|
+
await this.tdCache.incrby(key, duration);
|
113
|
+
|
114
|
+
this.sendEmailIfQuotaExceeded(project, request, 'voice_duration', key);
|
115
|
+
}
|
116
|
+
}
|
98
117
|
// INCREMENT KEY SECTION - END
|
99
118
|
|
100
119
|
|
@@ -228,7 +247,7 @@ class QuoteManager {
|
|
228
247
|
winston.verbose("limits for current plan: ", limits)
|
229
248
|
|
230
249
|
let quote = await this.getCurrentQuote(project, object, type);
|
231
|
-
winston.verbose("getCurrentQuote resp: "
|
250
|
+
winston.verbose("getCurrentQuote resp: " + quote)
|
232
251
|
|
233
252
|
if (quote == null) {
|
234
253
|
return true;
|
@@ -494,13 +513,21 @@ class QuoteManager {
|
|
494
513
|
if (quotes_enabled === true) {
|
495
514
|
winston.verbose("request.create.quote event catched");
|
496
515
|
let result = await this.incrementRequestsCount(payload.project, payload.request);
|
497
|
-
|
498
|
-
|
499
516
|
return result;
|
500
517
|
} else {
|
501
518
|
winston.verbose("QUOTES DISABLED - request.create.quote event")
|
502
519
|
}
|
503
520
|
})
|
521
|
+
|
522
|
+
requestEvent.on('request.close.quote', async (payload) => {
|
523
|
+
if (quotes_enabled === true) {
|
524
|
+
winston.verbose("request.close.quote event catched");
|
525
|
+
let result = await this.incrementVoiceDurationCount(payload.project, payload.request);
|
526
|
+
return result;
|
527
|
+
} else {
|
528
|
+
winston.verbose("QUOTES DISABLED - request.close.quote event")
|
529
|
+
}
|
530
|
+
})
|
504
531
|
// REQUESTS EVENTS - END
|
505
532
|
|
506
533
|
|
@@ -0,0 +1,151 @@
|
|
1
|
+
var winston = require('../config/winston');
|
2
|
+
const axios = require("axios").default;
|
3
|
+
require('dotenv').config();
|
4
|
+
|
5
|
+
class AiReindexService {
|
6
|
+
|
7
|
+
constructor() {
|
8
|
+
|
9
|
+
this.BASE_URL = process.env.SCHEDULER_BASEURL;
|
10
|
+
winston.verbose("(ReindexScheduler) BASE_URL: " + this.BASE_URL)
|
11
|
+
if (!this.BASE_URL) {
|
12
|
+
throw new Error("Missing paramter BASE_URL");
|
13
|
+
}
|
14
|
+
|
15
|
+
this.TOKEN = process.env.SCHEDULER_TOKEN;
|
16
|
+
winston.verbose("(ReindexScheduler) TOKEN: " + this.TOKEN)
|
17
|
+
if (!this.TOKEN) {
|
18
|
+
throw new Error("Missing paramter TOKEN");
|
19
|
+
}
|
20
|
+
|
21
|
+
this.PROJECT = process.env.SCHEDULER_PROJECT;
|
22
|
+
winston.verbose("(ReindexScheduler) PROJECT: " + this.PROJECT)
|
23
|
+
if (!this.PROJECT) {
|
24
|
+
throw new Error("Missing paramter PROJECT");
|
25
|
+
}
|
26
|
+
|
27
|
+
}
|
28
|
+
|
29
|
+
async delete(content_id) {
|
30
|
+
|
31
|
+
return new Promise( async (resolve, reject) => {
|
32
|
+
|
33
|
+
let scheduler = await this.findScheduler(content_id).catch((err) => {
|
34
|
+
reject(err);
|
35
|
+
})
|
36
|
+
|
37
|
+
winston.verbose("(AiReindexService) delete() - scheduler: ", scheduler);
|
38
|
+
|
39
|
+
if (!scheduler) {
|
40
|
+
reject("Scheduler not found for content id " + content_id);
|
41
|
+
}
|
42
|
+
|
43
|
+
let isOfflineS = await this.offlineScheduler(scheduler.id).catch((err) => {
|
44
|
+
reject(err);
|
45
|
+
})
|
46
|
+
|
47
|
+
winston.verbose("(AiReindexService) delete() - isOfflineS: ", isOfflineS)
|
48
|
+
|
49
|
+
let isOffline = await this.offlineWorkflow(scheduler.processDefinitionCode).catch((err) => {
|
50
|
+
reject(err);
|
51
|
+
})
|
52
|
+
|
53
|
+
winston.verbose("(AiReindexService) delete() - isOffline: ", isOffline)
|
54
|
+
|
55
|
+
let deleteResponse = await this.deleteWorkflow(scheduler.processDefinitionCode).catch((err) => {
|
56
|
+
reject(err);
|
57
|
+
})
|
58
|
+
|
59
|
+
winston.verbose("(AiReindexService) delete() - deleteResponse: ", deleteResponse)
|
60
|
+
|
61
|
+
resolve(deleteResponse);
|
62
|
+
})
|
63
|
+
}
|
64
|
+
|
65
|
+
async findScheduler(id) {
|
66
|
+
|
67
|
+
return new Promise( async (resolve, reject) => {
|
68
|
+
await axios({
|
69
|
+
url: `${this.BASE_URL}/projects/${this.PROJECT}/schedules/list`,
|
70
|
+
method: 'POST',
|
71
|
+
headers: {
|
72
|
+
token: this.TOKEN
|
73
|
+
}
|
74
|
+
}).then((response) => {
|
75
|
+
|
76
|
+
let scheduler = response.data.data.find(s => s.processDefinitionName === "auto-reindex-" + id);
|
77
|
+
if (!scheduler) {
|
78
|
+
resolve(null);
|
79
|
+
} else {
|
80
|
+
resolve(scheduler);
|
81
|
+
|
82
|
+
}
|
83
|
+
|
84
|
+
}).catch((err) => {
|
85
|
+
reject(err);
|
86
|
+
})
|
87
|
+
})
|
88
|
+
}
|
89
|
+
|
90
|
+
async offlineScheduler(id) {
|
91
|
+
|
92
|
+
return new Promise( async (resolve, reject) => {
|
93
|
+
await axios({
|
94
|
+
url: `${this.BASE_URL}/projects/${this.PROJECT}/schedules/${id}/offline`,
|
95
|
+
method: 'POST',
|
96
|
+
headers: {
|
97
|
+
token: this.TOKEN
|
98
|
+
}
|
99
|
+
}).then((response) => {
|
100
|
+
resolve(response.data);
|
101
|
+
}).catch((err) => {
|
102
|
+
reject(err);
|
103
|
+
})
|
104
|
+
})
|
105
|
+
}
|
106
|
+
|
107
|
+
async offlineWorkflow(code) {
|
108
|
+
|
109
|
+
return new Promise( async (resolve, reject) => {
|
110
|
+
|
111
|
+
const queryParams = {
|
112
|
+
releaseState: "OFFLINE"
|
113
|
+
}
|
114
|
+
await axios({
|
115
|
+
url: `${this.BASE_URL}/projects/${this.PROJECT}/process-definition/${code}/release`,
|
116
|
+
method: 'POST',
|
117
|
+
headers: {
|
118
|
+
token: this.TOKEN
|
119
|
+
},
|
120
|
+
params: queryParams
|
121
|
+
}).then((response) => {
|
122
|
+
resolve(response.data);
|
123
|
+
}).catch((err) => {
|
124
|
+
reject(err);
|
125
|
+
})
|
126
|
+
})
|
127
|
+
}
|
128
|
+
|
129
|
+
async deleteWorkflow(code) {
|
130
|
+
|
131
|
+
return new Promise( async (resolve, reject) => {
|
132
|
+
|
133
|
+
const queryParams = {
|
134
|
+
releaseState: "OFFLINE"
|
135
|
+
}
|
136
|
+
await axios({
|
137
|
+
url: `${this.BASE_URL}/projects/${this.PROJECT}/process-definition/${code}`,
|
138
|
+
method: 'DELETE',
|
139
|
+
headers: {
|
140
|
+
token: this.TOKEN
|
141
|
+
}
|
142
|
+
}).then((response) => {
|
143
|
+
resolve(response.data);
|
144
|
+
}).catch((err) => {
|
145
|
+
reject(err);
|
146
|
+
})
|
147
|
+
})
|
148
|
+
}
|
149
|
+
}
|
150
|
+
|
151
|
+
module.exports = { AiReindexService };
|
@@ -9,7 +9,7 @@ let kb_endpoint_train = process.env.KB_ENDPOINT_TRAIN;
|
|
9
9
|
let kb_endpoint_qa = process.env.KB_ENDPOINT_QA;
|
10
10
|
let secret = process.env.JWT_SECRET_KEY;
|
11
11
|
|
12
|
-
class
|
12
|
+
class AiService {
|
13
13
|
|
14
14
|
// OPEN AI
|
15
15
|
completions(data, gptkey) {
|
@@ -228,6 +228,6 @@ class OpenaiService {
|
|
228
228
|
|
229
229
|
}
|
230
230
|
|
231
|
-
var
|
231
|
+
var aiService = new AiService();
|
232
232
|
|
233
|
-
module.exports =
|
233
|
+
module.exports = aiService;
|