@tiledesk/tiledesk-tybot-connector 0.2.601-rc1 → 0.3.1

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.
Files changed (73) hide show
  1. package/CHANGELOG.md +387 -1
  2. package/ExtApi.js +6 -7
  3. package/Logger.js +74 -0
  4. package/TdCache.js +81 -176
  5. package/TdCache_v3.js +261 -0
  6. package/TiledeskExpression.js +7 -3
  7. package/TiledeskServices/AIService.js +43 -0
  8. package/TiledeskServices/utils.js +99 -0
  9. package/index.js +305 -50
  10. package/logs/app.log +279 -0
  11. package/models/IntentsMachineFactory.js +5 -2
  12. package/models/MockBotsDataSource.js +19 -11
  13. package/models/TiledeskChatbot.js +97 -79
  14. package/models/TiledeskChatbotConst.js +12 -17
  15. package/models/TiledeskChatbotUtil.js +359 -109
  16. package/models/TiledeskIntentsMachine.js +1 -1
  17. package/models/faqKbService.js +1 -1
  18. package/package.json +8 -6
  19. package/tiledeskChatbotPlugs/DirectivesChatbotPlug.js +172 -106
  20. package/tiledeskChatbotPlugs/Filler.js +13 -2
  21. package/tiledeskChatbotPlugs/TildeskContextForCodeOrchestrator.js +8 -0
  22. package/tiledeskChatbotPlugs/WebhookChatbotPlug.js +13 -7
  23. package/tiledeskChatbotPlugs/directives/DirAddTags.js +374 -0
  24. package/tiledeskChatbotPlugs/directives/DirAiPrompt.js +476 -0
  25. package/tiledeskChatbotPlugs/directives/DirAskGPT.js +16 -19
  26. package/tiledeskChatbotPlugs/directives/DirAskGPTV2.js +221 -34
  27. package/tiledeskChatbotPlugs/directives/DirAssign.js +0 -11
  28. package/tiledeskChatbotPlugs/directives/DirAssignFromFunction.js +11 -21
  29. package/tiledeskChatbotPlugs/directives/DirAssistant.js +728 -0
  30. package/tiledeskChatbotPlugs/directives/DirBrevo.js +353 -0
  31. package/tiledeskChatbotPlugs/directives/DirCaptureUserReply.js +3 -30
  32. package/tiledeskChatbotPlugs/directives/DirClearTranscript.js +22 -0
  33. package/tiledeskChatbotPlugs/directives/DirClose.js +16 -3
  34. package/tiledeskChatbotPlugs/directives/DirCode.js +1 -1
  35. package/tiledeskChatbotPlugs/directives/DirCondition.js +0 -26
  36. package/tiledeskChatbotPlugs/directives/DirConnectBlock.js +182 -0
  37. package/tiledeskChatbotPlugs/directives/DirContactUpdate.js +121 -0
  38. package/tiledeskChatbotPlugs/directives/DirCustomerio.js +5 -8
  39. package/tiledeskChatbotPlugs/directives/DirDeflectToHelpCenter.js +11 -1
  40. package/tiledeskChatbotPlugs/directives/DirDepartment.js +15 -6
  41. package/tiledeskChatbotPlugs/directives/DirFireTiledeskEvent.js +17 -6
  42. package/tiledeskChatbotPlugs/directives/DirForm.js +12 -2
  43. package/tiledeskChatbotPlugs/directives/DirGptTask.js +83 -38
  44. package/tiledeskChatbotPlugs/directives/DirGptTask_OLD.js +4 -7
  45. package/tiledeskChatbotPlugs/directives/DirHubspot.js +5 -8
  46. package/tiledeskChatbotPlugs/directives/DirIfOnlineAgents.js +14 -27
  47. package/tiledeskChatbotPlugs/directives/DirIfOnlineAgentsV2.js +278 -0
  48. package/tiledeskChatbotPlugs/directives/DirIfOpenHours.js +147 -51
  49. package/tiledeskChatbotPlugs/directives/DirIfOpenHours_OLD.js +125 -0
  50. package/tiledeskChatbotPlugs/directives/DirIntent.js +8 -37
  51. package/tiledeskChatbotPlugs/directives/DirJSONCondition.js +5 -26
  52. package/tiledeskChatbotPlugs/directives/DirMessage.js +19 -17
  53. package/tiledeskChatbotPlugs/directives/DirMessageToBot.js +135 -0
  54. package/tiledeskChatbotPlugs/directives/DirMoveToAgent.js +20 -87
  55. package/tiledeskChatbotPlugs/directives/DirMoveToUnassigned.js +59 -0
  56. package/tiledeskChatbotPlugs/directives/DirQapla.js +6 -9
  57. package/tiledeskChatbotPlugs/directives/DirRandomReply.js +17 -7
  58. package/tiledeskChatbotPlugs/directives/DirRemoveCurrentBot.js +17 -7
  59. package/tiledeskChatbotPlugs/directives/DirReplaceBot.js +11 -2
  60. package/tiledeskChatbotPlugs/directives/DirReplaceBotV2.js +135 -21
  61. package/tiledeskChatbotPlugs/directives/DirReplaceBotV3.js +163 -0
  62. package/tiledeskChatbotPlugs/directives/DirReply.js +53 -9
  63. package/tiledeskChatbotPlugs/directives/DirReplyV2.js +347 -0
  64. package/tiledeskChatbotPlugs/directives/DirSendEmail.js +13 -23
  65. package/tiledeskChatbotPlugs/directives/DirSendWhatsapp.js +247 -0
  66. package/tiledeskChatbotPlugs/directives/DirSetAttributeV2.js +202 -15
  67. package/tiledeskChatbotPlugs/directives/DirSetConversationTags.js +13 -4
  68. package/tiledeskChatbotPlugs/directives/DirWait.js +21 -4
  69. package/tiledeskChatbotPlugs/directives/DirWebRequest.js +1 -2
  70. package/tiledeskChatbotPlugs/directives/DirWebRequestV2.js +166 -103
  71. package/tiledeskChatbotPlugs/directives/DirWhatsappByAttribute.js +2 -60
  72. package/tiledeskChatbotPlugs/directives/Directives.js +16 -1
  73. /package/tiledeskChatbotPlugs/directives/{DirOfflineHours.js → DEPRECATED_DirOfflineHours.js} +0 -0
@@ -0,0 +1,121 @@
1
+ const { Filler } = require('../Filler');
2
+ const { TiledeskChatbot } = require('../../models/TiledeskChatbot');
3
+ const { TiledeskChatbotUtil } = require('../../models/TiledeskChatbotUtil');
4
+ let axios = require('axios');
5
+ const { TiledeskChatbotConst } = require('../../models/TiledeskChatbotConst');
6
+ const { TiledeskClient } = require('@tiledesk/tiledesk-client');
7
+
8
+ class DirContactUpdate {
9
+
10
+ constructor(context) {
11
+ if (!context) {
12
+ throw new Error('context object is mandatory.');
13
+ }
14
+ this.context = context;
15
+ this.projectId = context.projectId;
16
+ this.requestId = context.requestId;
17
+ this.supportRequest = context.supportRequest;
18
+ this.token = context.token;
19
+ this.tdcache = context.tdcache;
20
+ this.API_ENDPOINT = context.API_ENDPOINT;
21
+ this.log = context.log;
22
+
23
+ this.tdClient = new TiledeskClient({
24
+ projectId: this.context.projectId,
25
+ token: this.context.token,
26
+ APIURL: this.API_ENDPOINT,
27
+ APIKEY: "___",
28
+ log: this.log
29
+ });
30
+ }
31
+
32
+ execute(directive, callback) {
33
+ let action;
34
+ if (directive.action) {
35
+ action = directive.action;
36
+ if (!action.attributes) {
37
+ action.attributes = {}
38
+ }
39
+ action.attributes.fillParams = true;
40
+ }
41
+ else {
42
+ console.error("Incorrect directive (no action provided):", directive);
43
+ callback();
44
+ return;
45
+ }
46
+ this.go(action, () => {
47
+ callback();
48
+ });
49
+ }
50
+
51
+ async go(action, callback) {
52
+ if (this.log) {console.log("(DirContactUpdate) start. Update properties:", action.update); }
53
+ const contactProperties = action.update;
54
+
55
+ // fill
56
+ let requestAttributes = null;
57
+ if (this.tdcache) {
58
+ requestAttributes =
59
+ await TiledeskChatbot.allParametersStatic(
60
+ this.tdcache, this.requestId
61
+ );
62
+ }
63
+ const filler = new Filler();
64
+ let updateProperties = {}
65
+ for (const [key, value] of Object.entries(contactProperties)) {
66
+ let filled_value = filler.fill(value, requestAttributes);
67
+ if (this.log) {console.log("(DirContactUpdate) setting property key:",key, "with value:", value, "filled value:", filled_value); }
68
+ updateProperties[key] = filled_value;
69
+ // it's important that all the lead's properties are immediatly updated in the current flow invocation so the updated values will be available in the next actions
70
+ if (key === "fullname") {
71
+ await this.context.chatbot.addParameter(TiledeskChatbotConst.REQ_LEAD_USERFULLNAME_KEY, filled_value);
72
+ if (this.log) {console.log("(DirContactUpdate) updating attribute:",TiledeskChatbotConst.REQ_LEAD_USERFULLNAME_KEY, "with property key:", key, "and value:", filled_value); }
73
+ }
74
+ else if ( key === "email") {
75
+ await this.context.chatbot.addParameter(TiledeskChatbotConst.REQ_LEAD_EMAIL_KEY, filled_value);
76
+ if (this.log) {console.log("(DirContactUpdate) updating attribute:",TiledeskChatbotConst.REQ_LEAD_EMAIL_KEY, "with property key:", key, "and value:", filled_value); }
77
+ }
78
+ // else if (key === "phone") {
79
+ // static REQ_USER_PHONE_KEY = "userPhone";
80
+ // }
81
+ if (this.log) {console.log("(DirContactUpdate) updating property:", key, "value:", filled_value); }
82
+ }
83
+ const leadId = requestAttributes[TiledeskChatbotConst.REQ_USER_LEAD_ID_KEY];
84
+ this.tdClient.updateLead(leadId, updateProperties, null, null, () => {
85
+ if (this.log) {console.log("(DirContactUpdate) Lead updated.", updateProperties);}
86
+ // send hidden info to update widget lead fullname only if it is a conversation!
87
+ if (this.log) {console.log("(DirContactUpdate) requestId:", this.requestId); }
88
+ if (this.log) {console.log("(DirContactUpdate) updateProperties:", updateProperties); }
89
+ if (this.log) {console.log("(DirContactUpdate) updateProperties['fullname']:", updateProperties['fullname']); }
90
+ callback();
91
+ // if (this.requestId.startsWith("support-group") && updateProperties['userFullname']) {
92
+ // if (this.log) {console.log("(DirContactUpdate) send hidden info to update widget lead fullname"); }
93
+ // const userFullname = updateProperties['fullname'];
94
+ // const updateLeadDataOnWidgetMessage = {
95
+ // type: "text",
96
+ // text: "Updated lead fullname on widget with: " + userFullname,
97
+ // attributes: {
98
+ // // subtype: "info",
99
+ // updateUserFullname: userFullname
100
+ // }
101
+ // };
102
+ // if (this.log) {console.log("(DirContactUpdate) sending updateLeadDataOnWidgetMessage:", updateLeadDataOnWidgetMessage); }
103
+ // this.tdClient.sendSupportMessage(
104
+ // this.requestId,
105
+ // updateLeadDataOnWidgetMessage,
106
+ // (err) => {
107
+ // if (err) {
108
+ // console.error("(DirContactUpdate) Error sending reply:", err);
109
+ // }
110
+ // if (this.log) {console.log("(DirContactUpdate) hidden message sent:", updateLeadDataOnWidgetMessage);}
111
+ // callback();
112
+ // });
113
+ // }
114
+ // else {
115
+ // callback();
116
+ // }
117
+ });
118
+ }
119
+ }
120
+
121
+ module.exports = { DirContactUpdate };
@@ -16,6 +16,7 @@ class DirCustomerio {
16
16
  this.tdcache = this.context.tdcache;
17
17
  this.requestId = this.context.requestId;
18
18
  this.intentDir = new DirIntent(context);
19
+ this.API_ENDPOINT = this.context.API_ENDPOINT;
19
20
  this.log = context.log;
20
21
  }
21
22
 
@@ -69,14 +70,10 @@ class DirCustomerio {
69
70
  return;
70
71
  }
71
72
 
72
- const server_base_url = process.env.API_ENDPOINT || process.env.API_URL;
73
73
  const customerio_base_url = process.env.CUSTOMERIO_ENDPOINT || "https://track.customer.io/api/v1";
74
- if (this.log) {
75
- console.log("DirCustomerio server_base_url: ", server_base_url);
76
- console.log("DirCustomerio customerio_base_url: ", customerio_base_url);
77
- }
74
+ if (this.log) { console.log("DirCustomerio customerio_base_url: ", customerio_base_url); }
78
75
 
79
- let key = await this.getKeyFromIntegrations(server_base_url);
76
+ let key = await this.getKeyFromIntegrations();
80
77
  if (!key) {
81
78
  if (this.log) { console.log("DirCustomerio - Key not found in Integrations."); }
82
79
  let status = 422;
@@ -287,11 +284,11 @@ class DirCustomerio {
287
284
  }
288
285
  }
289
286
 
290
- async getKeyFromIntegrations(server_base_url) {
287
+ async getKeyFromIntegrations() {
291
288
  return new Promise((resolve) => {
292
289
 
293
290
  const INTEGRATIONS_HTTPREQUEST = {
294
- url: server_base_url + "/" + this.context.projectId + "/integration/name/customerio",
291
+ url: this.API_ENDPOINT + "/" + this.context.projectId + "/integration/name/customerio",
295
292
  headers: {
296
293
  'Content-Type': 'application/json',
297
294
  'Authorization': 'JWT ' + this.context.token
@@ -2,6 +2,7 @@ const { HelpCenterQuery } = require('@tiledesk/helpcenter-query-client');
2
2
  const { TiledeskChatbot } = require('../../models/TiledeskChatbot.js');
3
3
  const { TiledeskChatbotConst } = require('../../models/TiledeskChatbotConst');
4
4
  const ms = require('minimist-string');
5
+ const { TiledeskClient } = require('@tiledesk/tiledesk-client');
5
6
 
6
7
  class DirDeflectToHelpCenter {
7
8
 
@@ -10,7 +11,16 @@ class DirDeflectToHelpCenter {
10
11
  throw new Error('context object is mandatory.');
11
12
  }
12
13
  this.context = context;
14
+ this.API_ENDPOINT = context.API_ENDPOINT;
13
15
  this.log = context.log;
16
+
17
+ this.tdClient = new TiledeskClient({
18
+ projectId: this.context.projectId,
19
+ token: this.context.token,
20
+ APIURL: this.API_ENDPOINT,
21
+ APIKEY: "___",
22
+ log: this.log
23
+ });
14
24
  }
15
25
 
16
26
  async execute(directive, callback) {
@@ -132,7 +142,7 @@ class DirDeflectToHelpCenter {
132
142
  }
133
143
 
134
144
  if (this.log) {console.log("HC reply:", JSON.stringify(message))};
135
- this.context.tdclient.sendSupportMessage(
145
+ this.tdClient.sendSupportMessage(
136
146
  this.context.requestId,
137
147
  message,
138
148
  (err) => {
@@ -1,3 +1,4 @@
1
+ const { TiledeskClient } = require("@tiledesk/tiledesk-client");
1
2
 
2
3
  class DirDepartment {
3
4
 
@@ -6,9 +7,17 @@ class DirDepartment {
6
7
  throw new Error('context object is mandatory.');
7
8
  }
8
9
  this.context = context;
9
- this.log = context.log;
10
- this.tdclient = context.tdclient;
11
10
  this.requestId = context.requestId;
11
+ this.API_ENDPOINT = context.API_ENDPOINT;
12
+ this.log = context.log;
13
+
14
+ this.tdClient = new TiledeskClient({
15
+ projectId: this.context.projectId,
16
+ token: this.context.token,
17
+ APIURL: this.API_ENDPOINT,
18
+ APIKEY: "___",
19
+ log: this.log
20
+ });
12
21
  }
13
22
 
14
23
  execute(directive, callback) {
@@ -80,7 +89,7 @@ class DirDepartment {
80
89
  subtype: "info"
81
90
  }
82
91
  }
83
- this.tdclient.sendSupportMessage(
92
+ this.tdClient.sendSupportMessage(
84
93
  this.requestId,
85
94
  message, (err) => {
86
95
  if (err) {
@@ -99,7 +108,7 @@ class DirDepartment {
99
108
  }
100
109
 
101
110
  moveToDepartment(requestId, depName, callback) {
102
- this.tdclient.getAllDepartments((err, deps) => {
111
+ this.tdClient.getAllDepartments((err, deps) => {
103
112
  if (this.log) {console.log("deps:", JSON.stringify(deps));}
104
113
  if (err) {
105
114
  console.error("getAllDepartments() error:", err);
@@ -116,13 +125,13 @@ class DirDepartment {
116
125
  }
117
126
  }
118
127
  if (dep) {
119
- this.tdclient.updateRequestDepartment(requestId, dep._id, null, (err, res) => {
128
+ this.tdClient.updateRequestDepartment(requestId, dep._id, null, (err, res) => {
120
129
  if (err) {
121
130
  console.error("DirDepartment error:", err);
122
131
  callback();
123
132
  }
124
133
  else {
125
- console.log("DirDepartment response:",JSON.stringify(res));
134
+ if (this.log) { console.log("DirDepartment response:",JSON.stringify(res)); }
126
135
  callback(deps);
127
136
  }
128
137
  });
@@ -1,13 +1,24 @@
1
+ const { TiledeskClient } = require('@tiledesk/tiledesk-client');
1
2
  const ms = require('minimist-string');
2
3
 
3
4
  class DirFireTiledeskEvent {
4
5
 
5
- constructor(config) {
6
- if (!config.tdclient) {
7
- throw new Error('config.tdclient (TiledeskClient) object is mandatory.');
6
+ constructor(context) {
7
+ if (!context) {
8
+ throw new Error('context object is mandatory.');
8
9
  }
9
- this.tdclient = config.tdclient;
10
- this.log = config.log;
10
+
11
+ this.context = context;
12
+ this.log = context.log;
13
+
14
+ this.API_ENDPOINT = context.API_ENDPOINT;
15
+ this.tdClient = new TiledeskClient({
16
+ projectId: this.context.projectId,
17
+ token: this.context.token,
18
+ APIURL: this.API_ENDPOINT,
19
+ APIKEY: "___",
20
+ log: this.log
21
+ });
11
22
  }
12
23
 
13
24
  execute(directive, callback) {
@@ -18,7 +29,7 @@ class DirFireTiledeskEvent {
18
29
  name: event_name,
19
30
  attributes: params.payload
20
31
  }
21
- this.tdclient.fireEvent(event, function(err, result) {
32
+ this.tdClient.fireEvent(event, function(err, result) {
22
33
  if (err) {
23
34
  console.error("An error occurred invoking an event:", err);
24
35
  }
@@ -2,6 +2,7 @@ const { Filler } = require('../Filler');
2
2
  const { TiledeskChatbot } = require('../../models/TiledeskChatbot');
3
3
  const { DirIntent } = require('./DirIntent');
4
4
  const { IntentForm } = require('../../models/IntentForm.js');
5
+ const { TiledeskClient } = require('@tiledesk/tiledesk-client');
5
6
 
6
7
  class DirForm {
7
8
  constructor(context) {
@@ -9,12 +10,21 @@ class DirForm {
9
10
  throw new Error('context object is mandatory.');
10
11
  }
11
12
  this.context = context;
12
- this.tdclient = context.tdclient;
13
13
  this.chatbot = context.chatbot;
14
14
  this.tdcache = context.tdcache;
15
15
  this.requestId = context.requestId;
16
16
  this.intentDir = new DirIntent(context);
17
17
  this.log = context.log;
18
+
19
+ this.API_ENDPOINT = context.API_ENDPOINT;
20
+ this.tdClient = new TiledeskClient({
21
+ projectId: this.context.projectId,
22
+ token: this.context.token,
23
+ APIURL: this.API_ENDPOINT,
24
+ APIKEY: "___",
25
+ log: this.log
26
+ });
27
+
18
28
  }
19
29
 
20
30
  execute(directive, callback) {
@@ -83,7 +93,7 @@ class DirForm {
83
93
  form_reply.message.attributes.markbot = true;
84
94
  // return form_reply.message;
85
95
 
86
- this.context.tdclient.sendSupportMessage(
96
+ this.tdClient.sendSupportMessage(
87
97
  this.requestId,
88
98
  form_reply.message,
89
99
  (err) => {
@@ -3,6 +3,8 @@ const { TiledeskChatbot } = require("../../models/TiledeskChatbot");
3
3
  const { Filler } = require("../Filler");
4
4
  let https = require("https");
5
5
  const { DirIntent } = require("./DirIntent");
6
+ const { TiledeskChatbotConst } = require("../../models/TiledeskChatbotConst");
7
+ const { TiledeskChatbotUtil } = require("../../models/TiledeskChatbotUtil");
6
8
  require('dotenv').config();
7
9
 
8
10
  class DirGptTask {
@@ -12,9 +14,11 @@ class DirGptTask {
12
14
  throw new Error('context object is mandatory');
13
15
  }
14
16
  this.context = context;
17
+ this.chatbot = this.context.chatbot;
15
18
  this.tdcache = this.context.tdcache;
16
19
  this.requestId = this.context.requestId;
17
20
  this.intentDir = new DirIntent(context);
21
+ this.API_ENDPOINT = this.context.API_ENDPOINT;
18
22
  this.log = context.log;
19
23
  }
20
24
 
@@ -47,6 +51,7 @@ class DirGptTask {
47
51
  let falseIntent = action.falseIntent;
48
52
  let trueIntentAttributes = action.trueIntentAttributes;
49
53
  let falseIntentAttributes = action.falseIntentAttributes;
54
+ let transcript;
50
55
 
51
56
  if (this.log) {
52
57
  console.log("DirGptTask trueIntent", trueIntent)
@@ -57,10 +62,12 @@ class DirGptTask {
57
62
 
58
63
  // default value
59
64
  let answer = "No answer.";
65
+ let model = "gpt-3.5-turbo";
60
66
 
61
67
  if (!action.question || action.question === '') {
62
68
  console.error("Error: DirGptTask question attribute is mandatory. Executing condition false...")
63
69
  if (falseIntent) {
70
+ await this.chatbot.addParameter("flowError", "GPT Error: question attribute is undefined");
64
71
  await this.#executeCondition(false, trueIntent, trueIntentAttributes, falseIntent, falseIntentAttributes);
65
72
  callback(true);
66
73
  return;
@@ -81,23 +88,38 @@ class DirGptTask {
81
88
 
82
89
  let max_tokens = action.max_tokens;
83
90
  let temperature = action.temperature;
91
+
92
+ if (action.model) {
93
+ model = action.model;
94
+ }
84
95
 
85
96
  if (this.log) {
86
97
  console.log("DirGptTask max_tokens: ", max_tokens);
87
98
  console.log("DirGptTask temperature: ", temperature);
88
99
  }
89
100
 
90
- const server_base_url = process.env.API_ENDPOINT || process.env.API_URL;
91
- const openai_url = process.env.OPENAI_ENDPOINT + "/chat/completions";
92
- if (this.log) {
93
- console.log("DirGptTask server_base_url ", server_base_url);
94
- console.log("DirGptTask openai_url ", openai_url);
101
+ if (action.history) {
102
+ let transcript_string = await TiledeskChatbot.getParameterStatic(
103
+ this.context.tdcache,
104
+ this.context.requestId,
105
+ TiledeskChatbotConst.REQ_TRANSCRIPT_KEY);
106
+ if (this.log) { console.log("DirGptTask transcript string: ", transcript_string) }
107
+
108
+ if (transcript_string) {
109
+ transcript = await TiledeskChatbotUtil.transcriptJSON(transcript_string);
110
+ if (this.log) { console.log("DirGptTask transcript: ", transcript) }
111
+ } else {
112
+ if (this.log) { console.log("DirGptTask transcript_string is undefined. Skip JSON translation for chat history") }
113
+ }
95
114
  }
96
115
 
97
- let key = await this.getKeyFromIntegrations(server_base_url);
116
+ const openai_url = process.env.OPENAI_ENDPOINT + "/chat/completions";
117
+ if (this.log) { console.log("DirGptTask openai_url ", openai_url); }
118
+
119
+ let key = await this.getKeyFromIntegrations();
98
120
  if (!key) {
99
121
  if (this.log) { console.log("DirGptTask - Key not found in Integrations. Searching in kb settings..."); }
100
- key = await this.getKeyFromKbSettings(server_base_url);
122
+ key = await this.getKeyFromKbSettings();
101
123
  }
102
124
 
103
125
  if (!key) {
@@ -110,6 +132,7 @@ class DirGptTask {
110
132
  console.error("DirGptTask gptkey is mandatory");
111
133
  await this.#assignAttributes(action, answer);
112
134
  if (falseIntent) {
135
+ await this.chatbot.addParameter("flowError", "GPT Error: gpt apikey is undefined");
113
136
  await this.#executeCondition(false, trueIntent, trueIntentAttributes, falseIntent, falseIntentAttributes);
114
137
  callback(true);
115
138
  return;
@@ -119,9 +142,11 @@ class DirGptTask {
119
142
  }
120
143
 
121
144
  if (publicKey === true) {
122
- let keep_going = await this.checkQuoteAvailability(server_base_url);
145
+ let keep_going = await this.checkQuoteAvailability();
123
146
  if (keep_going === false) {
124
147
  if (this.log) { console.log("DirGptTask - Quota exceeded for tokens. Skip the action")}
148
+ await this.chatbot.addParameter("flowError", "GPT Error: tokens quota exceeded");
149
+ await this.#executeCondition(false, trueIntent, trueIntentAttributes, falseIntent, falseIntentAttributes);
125
150
  callback();
126
151
  return;
127
152
  }
@@ -129,22 +154,35 @@ class DirGptTask {
129
154
 
130
155
  let json = {
131
156
  model: action.model,
132
- messages: [
133
- {
134
- role: "user",
135
- content: filled_question
136
- }
137
- ],
157
+ messages: [],
138
158
  max_tokens: action.max_tokens,
139
- temperature: action.temperature
159
+ temperature: action.temperature,
140
160
  }
141
161
 
142
- let message = { role: "", content: "" };
143
162
  if (action.context) {
144
- message.role = "system";
145
- message.content = filled_context;
146
- json.messages.unshift(message);
163
+ let message = { role: "system", content: filled_context }
164
+ json.messages.push(message);
165
+ }
166
+
167
+ if (transcript) {
168
+ transcript.forEach(msg => {
169
+ if (!msg.content.startsWith('/')) {
170
+ let message = { role: msg.role, content: msg.content }
171
+ json.messages.push(message)
172
+ }
173
+ })
174
+ json.messages.push({ role: "user", content: filled_question });
175
+ } else {
176
+ let message = { role: "user", content: filled_question };
177
+ json.messages.push(message);
178
+ }
179
+
180
+ if (action.formatType && action.formatType !== 'none') {
181
+ json.response_format = {
182
+ type: action.formatType
183
+ }
147
184
  }
185
+
148
186
  if (this.log) { console.log("DirGptTask json: ", json) }
149
187
 
150
188
  const HTTPREQUEST = {
@@ -162,10 +200,11 @@ class DirGptTask {
162
200
  if (err) {
163
201
  if (this.log) {
164
202
  console.error("(httprequest) DirGptTask openai err:", err);
165
- console.error("(httprequest) DirGptTask openai err:", err.response.data);
203
+ console.error("(httprequest) DirGptTask openai err:", err.response?.data?.error?.message);
166
204
  }
167
205
  await this.#assignAttributes(action, answer);
168
206
  if (falseIntent) {
207
+ await this.chatbot.addParameter("flowError", "GPT Error: " + err.response?.data?.error?.message);
169
208
  await this.#executeCondition(false, trueIntent, trueIntentAttributes, falseIntent, falseIntentAttributes);
170
209
  callback(true);
171
210
  return;
@@ -175,13 +214,19 @@ class DirGptTask {
175
214
  } else {
176
215
  if (this.log) { console.log("DirGptTask resbody: ", JSON.stringify(resbody)); }
177
216
  answer = resbody.choices[0].message.content;
178
- // check if answer is a json
179
- let answer_json = await this.convertToJson(answer);
180
- await this.#assignAttributes(action, answer_json);
217
+
218
+ if (action.formatType === 'json_object' || action.formatType === undefined || action.formatType === null) {
219
+ answer = await this.convertToJson(answer);
220
+ }
221
+
222
+ await this.#assignAttributes(action, answer);
181
223
 
182
224
  if (publicKey === true) {
183
- let token_usage = resbody.usage.total_tokens;
184
- this.updateQuote(server_base_url, token_usage);
225
+ let tokens_usage = {
226
+ tokens: resbody.usage.total_tokens,
227
+ model: json.model
228
+ }
229
+ this.updateQuote(tokens_usage);
185
230
  }
186
231
 
187
232
  if (trueIntent) {
@@ -312,17 +357,18 @@ class DirGptTask {
312
357
  }
313
358
  })
314
359
  .catch((error) => {
360
+ console.error("(DirGptTask) Axios error: ", JSON.stringify(error));
315
361
  if (callback) {
316
362
  callback(error, null);
317
363
  }
318
364
  });
319
365
  }
320
366
 
321
- async getKeyFromIntegrations(server_base_url) {
367
+ async getKeyFromIntegrations() {
322
368
  return new Promise((resolve) => {
323
369
 
324
370
  const INTEGRATIONS_HTTPREQUEST = {
325
- url: server_base_url + "/" + this.context.projectId + "/integration/name/openai",
371
+ url: this.API_ENDPOINT + "/" + this.context.projectId + "/integration/name/openai",
326
372
  headers: {
327
373
  'Content-Type': 'application/json',
328
374
  'Authorization': 'JWT ' + this.context.token
@@ -349,11 +395,11 @@ class DirGptTask {
349
395
  })
350
396
  }
351
397
 
352
- async getKeyFromKbSettings(server_base_url) {
398
+ async getKeyFromKbSettings() {
353
399
  return new Promise((resolve) => {
354
400
 
355
401
  const KB_HTTPREQUEST = {
356
- url: server_base_url + "/" + this.context.projectId + "/kbsettings",
402
+ url: this.API_ENDPOINT + "/" + this.context.projectId + "/kbsettings",
357
403
  headers: {
358
404
  'Content-Type': 'application/json',
359
405
  'Authorization': 'JWT ' + this.context.token
@@ -382,11 +428,11 @@ class DirGptTask {
382
428
  })
383
429
  }
384
430
 
385
- async checkQuoteAvailability(server_base_url) {
431
+ async checkQuoteAvailability() {
386
432
  return new Promise((resolve) => {
387
433
 
388
434
  const HTTPREQUEST = {
389
- url: server_base_url + "/" + this.context.projectId + "/quotes/tokens",
435
+ url: this.API_ENDPOINT + "/" + this.context.projectId + "/quotes/tokens",
390
436
  headers: {
391
437
  'Content-Type': 'application/json',
392
438
  'Authorization': 'JWT ' + this.context.token
@@ -398,7 +444,6 @@ class DirGptTask {
398
444
  this.#myrequest(
399
445
  HTTPREQUEST, async (err, resbody) => {
400
446
  if (err) {
401
- console.error("(httprequest) DirGptTask Check quote availability err: ", err);
402
447
  resolve(true)
403
448
  } else {
404
449
  if (resbody.isAvailable === true) {
@@ -412,16 +457,16 @@ class DirGptTask {
412
457
  })
413
458
  }
414
459
 
415
- async updateQuote(server_base_url, tokens) {
416
- return new Promise((resolve) => {
460
+ async updateQuote(tokens_usage) {
461
+ return new Promise((resolve, reject) => {
417
462
 
418
463
  const HTTPREQUEST = {
419
- url: server_base_url + "/" + this.context.projectId + "/quotes/incr/tokens",
464
+ url: this.API_ENDPOINT + "/" + this.context.projectId + "/quotes/incr/tokens",
420
465
  headers: {
421
466
  'Content-Type': 'application/json',
422
467
  'Authorization': 'JWT ' + this.context.token
423
468
  },
424
- json: { tokens: tokens },
469
+ json: tokens_usage,
425
470
  method: "POST"
426
471
  }
427
472
  if (this.log) { console.log("DirGptTask check quote availability HTTPREQUEST", HTTPREQUEST); }
@@ -430,9 +475,9 @@ class DirGptTask {
430
475
  HTTPREQUEST, async (err, resbody) => {
431
476
  if (err) {
432
477
  console.error("(httprequest) DirGptTask Increment tokens quote err: ", err);
433
- rejects(false)
478
+ reject(false)
434
479
  } else {
435
- console.log("(httprequest) DirGptTask Increment token quote resbody: ", resbody);
480
+ if (this.log) { console.log("(httprequest) DirGptTask Increment token quote resbody: ", resbody); }
436
481
  resolve(true);
437
482
  }
438
483
  }
@@ -15,6 +15,7 @@ class DirGptTask {
15
15
  this.tdcache = this.context.tdcache;
16
16
  this.requestId = this.context.requestId;
17
17
  this.intentDir = new DirIntent(context);
18
+ this.API_ENDPOINT = this.context.API_ENDPOINT;
18
19
  this.log = context.log;
19
20
  }
20
21
 
@@ -85,15 +86,11 @@ class DirGptTask {
85
86
  console.log("DirGptTask temperature: ", temperature);
86
87
  }
87
88
 
88
- const server_base_url = process.env.API_ENDPOINT || process.env.API_URL;
89
89
  const openai_url = process.env.OPENAI_ENDPOINT + "/chat/completions";
90
- if (this.log) {
91
- console.log("DirGptTask server_base_url ", server_base_url);
92
- console.log("DirGptTask openai_url ", openai_url);
93
- }
90
+ if (this.log) { console.log("DirGptTask openai_url ", openai_url); }
94
91
 
95
92
  const INTEGRATIONS_HTTPREQUEST = {
96
- url: server_base_url + "/" + this.context.projectId + "/integration/name/openai",
93
+ url: this.API_ENDPOINT + "/" + this.context.projectId + "/integration/name/openai",
97
94
  headers: {
98
95
  'Content-Type': 'application/json',
99
96
  'Authorization': 'JWT ' + this.context.token
@@ -127,7 +124,7 @@ class DirGptTask {
127
124
  if (this.log) { console.log("DirGptTask - Key not found in Integrations. Searching in kb settings..."); }
128
125
 
129
126
  const KB_HTTPREQUEST = {
130
- url: server_base_url + "/" + this.context.projectId + "/kbsettings",
127
+ url: this.API_ENDPOINT + "/" + this.context.projectId + "/kbsettings",
131
128
  headers: {
132
129
  'Content-Type': 'application/json',
133
130
  'Authorization': 'JWT ' + this.context.token