@tiledesk/tiledesk-tybot-connector 2.0.23 → 2.0.24

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tiledesk/tiledesk-tybot-connector",
3
- "version": "2.0.23",
3
+ "version": "2.0.24",
4
4
  "description": "Tiledesk Tybot connector",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -0,0 +1,105 @@
1
+ const httpUtils = require('../utils/HttpUtils');
2
+ const winston = require('../utils/winston');
3
+ const API_ENDPOINT = process.env.API_ENDPOINT;
4
+
5
+ class KBService {
6
+
7
+ constructor() { }
8
+
9
+ async getNamespace(id_project, token, name, id) {
10
+ return new Promise((resolve) => {
11
+ const http_request = {
12
+ url: API_ENDPOINT + "/" + id_project + "/kb/namespace/all",
13
+ headers: {
14
+ 'Content-Type': 'application/json',
15
+ 'Authorization': 'JWT ' + token
16
+ },
17
+ method: "GET"
18
+ }
19
+ winston.debug("Kb HttpRequest", http_request);
20
+
21
+ httpUtils.request(
22
+ http_request, async (err, namespaces) => {
23
+ if (err) {
24
+ winston.error("Error getting namespaces:", err);
25
+ reject(err);
26
+ } else {
27
+ winston.debug("Get namespaces response:", namespaces);
28
+ if (!Array.isArray(namespaces)) {
29
+ reject(new Error('Invalid response format'));
30
+ return;
31
+ }
32
+
33
+ let namespace;
34
+ if (name) {
35
+ namespace = namespaces.find(n => n.name === name);
36
+ } else {
37
+ namespace = namespaces.find(n => n.id === id);
38
+ }
39
+ resolve(namespace || null);
40
+ }
41
+ }
42
+ )
43
+ })
44
+ }
45
+
46
+ async getKeyFromKbSettings(id_project, token) {
47
+
48
+ return new Promise((resolve) => {
49
+ const http_request = {
50
+ url: API_ENDPOINT + "/" + id_project + "/kbsettings",
51
+ headers: {
52
+ 'Content-Type': 'application/json',
53
+ 'Authorization': 'JWT ' + token
54
+ },
55
+ method: "GET"
56
+ }
57
+ winston.debug("Kb HttpRequest", http_request);
58
+
59
+ httpUtils.request(
60
+ http_request, async (err, resbody) => {
61
+ if (err) {
62
+ winston.error("Error getting kb settings:", err?.response?.data);
63
+ resolve(null);
64
+ } else {
65
+ if (!resbody || !resbody.gptkey) {
66
+ resolve(null);
67
+ } else {
68
+ resolve(resbody.gptkey);
69
+ }
70
+ }
71
+ }
72
+ )
73
+ })
74
+ }
75
+
76
+ async addUnansweredQuestion(id_project, namespace, question, token) {
77
+
78
+ const json = { namespace, question };
79
+
80
+ return new Promise((resolve, reject) => {
81
+ const http_request = {
82
+ url: API_ENDPOINT + "/" + id_project + "/kb/unanswered/",
83
+ headers: {
84
+ 'Content-Type': 'application/json',
85
+ 'Authorization': 'JWT ' + token
86
+ },
87
+ method: "POST",
88
+ json: json
89
+ }
90
+ winston.debug("Kb HttpRequest", http_request);
91
+
92
+ httpUtils.request(http_request, (err, response) => {
93
+ if (err) {
94
+ winston.error("Error adding unanswered question:", err);
95
+ reject(err);
96
+ } else {
97
+ resolve(response);
98
+ }
99
+ });
100
+ });
101
+ }
102
+ }
103
+
104
+ const kbService = new KBService();
105
+ module.exports = kbService;
@@ -0,0 +1,69 @@
1
+ const httpUtils = require('../utils/HttpUtils');
2
+ const winston = require('../utils/winston');
3
+ const API_ENDPOINT = process.env.API_ENDPOINT;
4
+
5
+ class QuotasService {
6
+
7
+ constructor() { }
8
+
9
+ async checkQuoteAvailability(id_project, token) {
10
+ return new Promise((resolve) => {
11
+
12
+ const http_request = {
13
+ url: API_ENDPOINT + "/" + id_project + "/quotes/tokens",
14
+ headers: {
15
+ 'Content-Type': 'application/json',
16
+ 'Authorization': 'JWT ' + token
17
+ },
18
+ method: "GET"
19
+ }
20
+ winston.debug("QuotasService HttpRequest", http_request);
21
+
22
+ httpUtils.request(
23
+ http_request, async (err, resbody) => {
24
+ if (err) {
25
+ winston.error("Check quote availability err: ", err);
26
+ resolve(true)
27
+ } else {
28
+ if (resbody.isAvailable === true) {
29
+ resolve(true)
30
+ } else {
31
+ resolve(false)
32
+ }
33
+ }
34
+ }
35
+ )
36
+ })
37
+ }
38
+
39
+ async updateQuote(id_project, token, tokens_usage) {
40
+ return new Promise((resolve, reject) => {
41
+
42
+ const http_request = {
43
+ url: API_ENDPOINT + "/" + id_project + "/quotes/incr/tokens",
44
+ headers: {
45
+ 'Content-Type': 'application/json',
46
+ 'Authorization': 'JWT ' + token
47
+ },
48
+ json: tokens_usage,
49
+ method: "POST"
50
+ }
51
+ winston.debug("DirAskGPTV2 update quote HttpRequest ", http_request);
52
+
53
+ httpUtils.request(
54
+ http_request, async (err, resbody) => {
55
+ if (err) {
56
+ winston.error("Increment tokens quote err: ", err);
57
+ reject(false)
58
+ } else {
59
+ resolve(true);
60
+ }
61
+ }
62
+ )
63
+ })
64
+ }
65
+
66
+ }
67
+
68
+ const quotasService = new QuotasService();
69
+ module.exports = quotasService;
@@ -11,6 +11,8 @@ const winston = require('../../utils/winston');
11
11
  const httpUtils = require("../../utils/HttpUtils");
12
12
  const integrationService = require("../../services/IntegrationService");
13
13
  const { Logger } = require("../../Logger");
14
+ const kbService = require("../../services/KBService");
15
+ const quotasService = require("../../services/QuotasService");
14
16
 
15
17
  class DirAskGPTV2 {
16
18
 
@@ -169,7 +171,7 @@ class DirAskGPTV2 {
169
171
  if (!key) {
170
172
  this.logger.native("[Ask Knowledge Base] OpenAI key not found in Integration. Using shared OpenAI key");
171
173
  winston.verbose("DirAskGPTV2 - Key not found in Integrations. Searching in kb settings...");
172
- key = await this.getKeyFromKbSettings();
174
+ key = await kbService.getKeyFromKbSettings(this.projectId, this.token);
173
175
  }
174
176
 
175
177
  if (!key) {
@@ -193,7 +195,7 @@ class DirAskGPTV2 {
193
195
  }
194
196
 
195
197
  if (publicKey === true && !chunks_only) {
196
- let keep_going = await this.checkQuoteAvailability();
198
+ let keep_going = await quotasService.checkQuoteAvailability(this.projectId, this.token);
197
199
  if (keep_going === false) {
198
200
  this.logger.warn("[Ask Knowledge Base] Tokens quota exceeded. Skip the action")
199
201
  winston.verbose("DirAskGPTV2 - Quota exceeded for tokens. Skip the action")
@@ -344,7 +346,9 @@ class DirAskGPTV2 {
344
346
  tokens: resbody.prompt_token_size,
345
347
  model: json.model
346
348
  }
347
- this.updateQuote(tokens_usage);
349
+ quotasService.updateQuote(this.projectId, this.token, tokens_usage).catch((err) => {
350
+ winston.error("Error updating quota: ", err);
351
+ })
348
352
  }
349
353
 
350
354
  if (trueIntent) {
@@ -357,6 +361,10 @@ class DirAskGPTV2 {
357
361
  }
358
362
  } else {
359
363
  await this.#assignAttributes(action, answer, source);
364
+ kbService.addUnansweredQuestion(this.projectId, json.namespace, json.question, this.token).catch((err) => {
365
+ winston.error("DirAskGPTV2 - Error adding unanswered question: ", err);
366
+ this.logger.warn("[Ask Knowledge Base] Unable to add unanswered question", json.question, "to namespacae", json.namespace);
367
+ })
360
368
  if (falseIntent) {
361
369
  await this.#executeCondition(false, trueIntent, trueIntentAttributes, falseIntent, falseIntentAttributes);
362
370
  callback(true);
@@ -427,93 +435,6 @@ class DirAskGPTV2 {
427
435
  }
428
436
  }
429
437
 
430
- async getKeyFromKbSettings() {
431
- return new Promise((resolve) => {
432
-
433
- const KB_HTTPREQUEST = {
434
- url: this.API_ENDPOINT + "/" + this.context.projectId + "/kbsettings",
435
- headers: {
436
- 'Content-Type': 'application/json',
437
- 'Authorization': 'JWT ' + this.context.token
438
- },
439
- method: "GET"
440
- }
441
- winston.debug("DirAskGPTV2 KB HttpRequest", KB_HTTPREQUEST);
442
-
443
- httpUtils.request(
444
- KB_HTTPREQUEST, async (err, resbody) => {
445
- if (err) {
446
- winston.error("DirAskGPTV2 Get kb settings error ", err?.response?.data);
447
- resolve(null);
448
- } else {
449
- if (!resbody.gptkey) {
450
- resolve(null);
451
- } else {
452
- resolve(resbody.gptkey);
453
- }
454
- }
455
- }
456
- )
457
- })
458
- }
459
-
460
- async checkQuoteAvailability() {
461
- return new Promise((resolve) => {
462
-
463
- const HTTPREQUEST = {
464
- url: this.API_ENDPOINT + "/" + this.context.projectId + "/quotes/tokens",
465
- headers: {
466
- 'Content-Type': 'application/json',
467
- 'Authorization': 'JWT ' + this.context.token
468
- },
469
- method: "GET"
470
- }
471
- winston.debug("DirAskGPTV2 check quote availability HttpRequest", HTTPREQUEST);
472
-
473
- httpUtils.request(
474
- HTTPREQUEST, async (err, resbody) => {
475
- if (err) {
476
- winston.error("DirAskGPTV2 Check quote availability err: ", err);
477
- resolve(true)
478
- } else {
479
- if (resbody.isAvailable === true) {
480
- resolve(true)
481
- } else {
482
- resolve(false)
483
- }
484
- }
485
- }
486
- )
487
- })
488
- }
489
-
490
- async updateQuote(tokens_usage) {
491
- return new Promise((resolve, reject) => {
492
-
493
- const HTTPREQUEST = {
494
- url: this.API_ENDPOINT + "/" + this.context.projectId + "/quotes/incr/tokens",
495
- headers: {
496
- 'Content-Type': 'application/json',
497
- 'Authorization': 'JWT ' + this.context.token
498
- },
499
- json: tokens_usage,
500
- method: "POST"
501
- }
502
- winston.debug("DirAskGPTV2 update quote HttpRequest ", HTTPREQUEST);
503
-
504
- httpUtils.request(
505
- HTTPREQUEST, async (err, resbody) => {
506
- if (err) {
507
- winston.error("DirAskGPTV2 Increment tokens quote err: ", err);
508
- reject(false)
509
- } else {
510
- resolve(true);
511
- }
512
- }
513
- )
514
- })
515
- }
516
-
517
438
  /**
518
439
  * Transforms the transcirpt array in a dictionary like '0': { "question": "xxx", "answer":"xxx"}
519
440
  * merging consecutive messages with the same role in a single question or answer.