@tiledesk/tiledesk-tybot-connector 2.0.21-rc4 → 2.0.21

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.21-rc4",
3
+ "version": "2.0.21",
4
4
  "description": "Tiledesk Tybot connector",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -54,13 +54,13 @@ const { DirMoveToUnassigned } = require('./directives/DirMoveToUnassigned');
54
54
  const { DirAddTags } = require('./directives/DirAddTags');
55
55
  const { DirSendWhatsapp } = require('./directives/DirSendWhatsapp');
56
56
  const { DirReplaceBotV3 } = require('./directives/DirReplaceBotV3');
57
- const { DirAiPrompt } = require('./directives/DirAiPrompt');
57
+ const { DirAiTask, DirAiPrompt } = require('./directives/DirAiPrompt');
58
58
  const { DirWebResponse } = require('./directives/DirWebResponse');
59
59
  const { DirConnectBlock } = require('./directives/DirConnectBlock');
60
- const { DirAddKbContent } = require('./directives/DirAddKbContent');
61
- const { DirFlowLog } = require('./directives/DirFlowLog');
62
60
 
63
61
  const winston = require('../utils/winston');
62
+ const { DirFlowLog } = require('./directives/DirFlowLog');
63
+ const { DirAddKbContent } = require('./directives/DirAddKbContent');
64
64
 
65
65
  class DirectivesChatbotPlug {
66
66
 
@@ -219,13 +219,14 @@ class DirectivesChatbotPlug {
219
219
  directive_name = directive.name.toLowerCase();
220
220
  }
221
221
  if (directive && directive.action) {
222
- const action_id = directive.action["_tdActionId"];
223
- const locked_action_id = await this.chatbot.currentLockedAction(this.supportRequest.request_id);
224
- if ( locked_action_id && (locked_action_id !== action_id) ) {
225
- let next_dir = await this.nextDirective(this.directives);
226
- this.process(next_dir);
227
- return;
228
- }
222
+ const action_id = directive.action["_tdActionId"];
223
+ const locked_action_id = await this.chatbot.currentLockedAction(this.supportRequest.request_id);
224
+ if ( locked_action_id && (locked_action_id !== action_id) ) {
225
+ let next_dir = await this.nextDirective(this.directives);
226
+ this.process(next_dir);
227
+ return;
228
+ }
229
+
229
230
  }
230
231
  if (directive == null || (directive !== null && directive["name"] === undefined)) {
231
232
  winston.debug("(DirectivesChatbotPlug) stop process(). directive is (null?): ", directive);
@@ -703,19 +704,6 @@ class DirectivesChatbotPlug {
703
704
  }
704
705
  });
705
706
  }
706
- else if (directive_name === Directives.WEBHOOK) {
707
- // console.log(".....DirIntent")
708
- new DirIntent(context).execute(directive, async (stop) => {
709
- if (stop) {
710
- if (context.log) { console.log("Stopping Actions on:", JSON.stringify(directive));}
711
- this.theend();
712
- }
713
- else {
714
- let next_dir = await this.nextDirective(this.directives);
715
- this.process(next_dir);
716
- }
717
- });
718
- }
719
707
  else if (directive_name === Directives.WEB_RESPONSE) {
720
708
  new DirWebResponse(context).execute(directive, async () => {
721
709
  let next_dir = await this.nextDirective(this.directives);
@@ -728,12 +716,6 @@ class DirectivesChatbotPlug {
728
716
  this.process(next_dir);
729
717
  })
730
718
  }
731
- else if (directive_name === Directives.ADD_KB_CONTENT) {
732
- new DirAddKbContent(context).execute(directive, async () => {
733
- let next_dir = await this.nextDirective(this.directives);
734
- this.process(next_dir);
735
- });
736
- }
737
719
  else {
738
720
  let next_dir = await this.nextDirective(this.directives);
739
721
  this.process(next_dir);
@@ -116,6 +116,14 @@ class DirAddKbContent {
116
116
  }
117
117
  }
118
118
 
119
+ if (!namespace) {
120
+ this.logger.error("[Add to KnwoledgeBase] Namespace is undefined")
121
+ winston.verbose("[DirAddKbContent] - Error: namespace is undefined")
122
+ await this.chatbot.addParameter("flowError", "[DirAddKbContent] Error: namespace is undefined");
123
+ callback(true);
124
+ return;
125
+ }
126
+
119
127
  let ns;
120
128
 
121
129
  if (action.namespaceAsName) {
@@ -137,20 +145,12 @@ class DirAddKbContent {
137
145
  return;
138
146
  }
139
147
 
140
- if (ns.engine) {
141
- engine = ns.engine;
142
- } else {
143
- engine = await this.setDefaultEngine()
144
- }
148
+ // if (ns.engine) {
149
+ // engine = ns.engine;
150
+ // } else {
151
+ // engine = await this.setDefaultEngine(ns.hybrid);
152
+ // }
145
153
 
146
- if (!namespace) {
147
- this.logger.error("[Add to KnwoledgeBase] Namespace is undefined")
148
- winston.verbose("[DirAddKbContent] - Error: namespace is undefined")
149
- await this.chatbot.addParameter("flowError", "[DirAddKbContent] Error: namespace is undefined");
150
- callback(true);
151
- return;
152
- }
153
-
154
154
  let json = {
155
155
  content: filled_content,
156
156
  namespace: namespace,
@@ -314,18 +314,19 @@ class DirAddKbContent {
314
314
  })
315
315
  }
316
316
 
317
- async setDefaultEngine() {
318
- return new Promise((resolve) => {
319
- let engine = {
320
- name: "pinecone",
321
- type: process.env.PINECONE_TYPE,
322
- apikey: "",
323
- vector_size: 1536,
324
- index_name: process.env.PINECONE_INDEX
325
- }
326
- resolve(engine);
327
- })
328
- }
317
+ // async setDefaultEngine() {
318
+ // let isHybrid = hybrid === true;
319
+ // return new Promise((resolve) => {
320
+ // let engine = {
321
+ // name: "pinecone",
322
+ // type: isHybrid ? "serverless" : "pod",
323
+ // apikey: "",
324
+ // vector_size: 1536,
325
+ // index_name: isHybrid ? "hybrid_index" : "standard_index"
326
+ // }
327
+ // resolve(engine);
328
+ // })
329
+ // }
329
330
 
330
331
  }
331
332
 
@@ -11,10 +11,6 @@ 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 quotasService = require("../../services/QuotasService");
15
- const llmService = require("../../services/LLMService");
16
-
17
-
18
14
 
19
15
  class DirAskGPTV2 {
20
16
 
@@ -169,14 +165,11 @@ class DirAskGPTV2 {
169
165
  }
170
166
  }
171
167
 
172
- const kb_endpoint = process.env.KB_ENDPOINT_QA
173
- winston.verbose("DirAskGPTV2 KbEndpoint URL: " + kb_endpoint);
174
-
175
168
  let key = await integrationService.getKeyFromIntegrations(this.projectId, 'openai', this.token);
176
169
  if (!key) {
177
170
  this.logger.native("[Ask Knowledge Base] OpenAI key not found in Integration. Using shared OpenAI key");
178
171
  winston.verbose("DirAskGPTV2 - Key not found in Integrations. Searching in kb settings...");
179
- key = await llmService.getKeyFromKbSettings(this.projectId, this.token);
172
+ key = await this.getKeyFromKbSettings();
180
173
  }
181
174
 
182
175
  if (!key) {
@@ -200,7 +193,7 @@ class DirAskGPTV2 {
200
193
  }
201
194
 
202
195
  if (publicKey === true && !chunks_only) {
203
- let keep_going = await quotasService.checkQuoteAvailability(this.projectId, this.token);
196
+ let keep_going = await this.checkQuoteAvailability();
204
197
  if (keep_going === false) {
205
198
  this.logger.warn("[Ask Knowledge Base] Tokens quota exceeded. Skip the action")
206
199
  winston.verbose("DirAskGPTV2 - Quota exceeded for tokens. Skip the action")
@@ -211,6 +204,17 @@ class DirAskGPTV2 {
211
204
  }
212
205
  }
213
206
 
207
+ if (!namespace) {
208
+ this.logger.error("[Ask Knowledge Base] Namespace is undefined")
209
+ winston.verbose("DirAskGPTV2 - Error: namespace is undefined")
210
+ if (falseIntent) {
211
+ await this.chatbot.addParameter("flowError", "AskGPT Error: namespace is undefined");
212
+ await this.#executeCondition(false, trueIntent, trueIntentAttributes, falseIntent, falseIntentAttributes);
213
+ callback(true);
214
+ return;
215
+ }
216
+ }
217
+
214
218
  let ns;
215
219
 
216
220
  if (action.namespaceAsName) {
@@ -241,18 +245,7 @@ class DirAskGPTV2 {
241
245
  if (ns.engine) {
242
246
  engine = ns.engine;
243
247
  } else {
244
- engine = await this.setDefaultEngine()
245
- }
246
-
247
- if (!namespace) {
248
- this.logger.error("[Ask Knowledge Base] Namespace is undefined")
249
- winston.verbose("DirAskGPTV2 - Error: namespace is undefined")
250
- if (falseIntent) {
251
- await this.chatbot.addParameter("flowError", "AskGPT Error: namespace is undefined");
252
- await this.#executeCondition(false, trueIntent, trueIntentAttributes, falseIntent, falseIntentAttributes);
253
- callback(true);
254
- return;
255
- }
248
+ engine = await this.setDefaultEngine(ns.hybrid);
256
249
  }
257
250
 
258
251
  let json = {
@@ -277,7 +270,8 @@ class DirAskGPTV2 {
277
270
  json.chunks_only = chunks_only;
278
271
  }
279
272
 
280
- if (engine.type === 'serverless') {
273
+
274
+ if (ns.hybrid === true) {
281
275
  json.search_type = 'hybrid';
282
276
  json.alpha = alpha;
283
277
  }
@@ -298,6 +292,12 @@ class DirAskGPTV2 {
298
292
 
299
293
  winston.debug("DirAskGPTV2 json:", json);
300
294
 
295
+ let kb_endpoint = process.env.KB_ENDPOINT_QA;
296
+ if (ns.hybrid === true) {
297
+ kb_endpoint = process.env.KB_ENDPOINT_QA_GPU;
298
+ }
299
+ winston.verbose("DirAskGPTV2 KbEndpoint URL: " + kb_endpoint);
300
+
301
301
  const HTTPREQUEST = {
302
302
  url: kb_endpoint + "/qa",
303
303
  headers: {
@@ -344,9 +344,7 @@ class DirAskGPTV2 {
344
344
  tokens: resbody.prompt_token_size,
345
345
  model: json.model
346
346
  }
347
- quotasService.updateQuote(this.projectId, this.token, tokens_usage).catch((err) => {
348
- winston.error("Error updating quota: ", err);
349
- })
347
+ this.updateQuote(tokens_usage);
350
348
  }
351
349
 
352
350
  if (trueIntent) {
@@ -359,10 +357,6 @@ class DirAskGPTV2 {
359
357
  }
360
358
  } else {
361
359
  await this.#assignAttributes(action, answer, source);
362
- llmService.addUnansweredQuestion(this.projectId, json.namespace, json.question, this.token).catch((err) => {
363
- winston.error("DirAskGPTV2 - Error adding unanswered question: ", err);
364
- this.logger.warn("[Ask Knowledge Base] Unable to add unanswered question", json.question, "to namespacae", json.namespace);
365
- })
366
360
  if (falseIntent) {
367
361
  await this.#executeCondition(false, trueIntent, trueIntentAttributes, falseIntent, falseIntentAttributes);
368
362
  callback(true);
@@ -433,6 +427,93 @@ class DirAskGPTV2 {
433
427
  }
434
428
  }
435
429
 
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
+
436
517
  /**
437
518
  * Transforms the transcirpt array in a dictionary like '0': { "question": "xxx", "answer":"xxx"}
438
519
  * merging consecutive messages with the same role in a single question or answer.
@@ -513,14 +594,15 @@ class DirAskGPTV2 {
513
594
  })
514
595
  }
515
596
 
516
- async setDefaultEngine() {
597
+ async setDefaultEngine(hybrid = false) {
598
+ let isHybrid = hybrid === true;
517
599
  return new Promise((resolve) => {
518
600
  let engine = {
519
601
  name: "pinecone",
520
- type: process.env.PINECONE_TYPE,
602
+ type: isHybrid ? "serverless" : "pod",
521
603
  apikey: "",
522
604
  vector_size: 1536,
523
- index_name: process.env.PINECONE_INDEX
605
+ index_name: isHybrid ? "hybrid_index" : "standard_index"
524
606
  }
525
607
  resolve(engine);
526
608
  })
@@ -118,7 +118,7 @@ class DirWebRequestV2 {
118
118
  this.logger.native("[Web Request] resbody: ", resbody);
119
119
 
120
120
  if (err) {
121
- this.logger.error("[Web Request] error: ", err);
121
+ this.logger.error("WebRequest error: ", err);
122
122
  winston.log("webRequest error: ", err);
123
123
  if (callback) {
124
124
  if (falseIntent) {