@tiledesk/tiledesk-tybot-connector 2.0.46 → 2.0.48

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.46",
3
+ "version": "2.0.48",
4
4
  "description": "Tiledesk Tybot connector",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -73,9 +73,7 @@ class KBService {
73
73
  })
74
74
  }
75
75
 
76
- async addUnansweredQuestion(id_project, namespace, question, token) {
77
-
78
- const json = { namespace, question };
76
+ async addUnansweredQuestion(id_project, data, token) {
79
77
 
80
78
  return new Promise((resolve, reject) => {
81
79
  const http_request = {
@@ -85,7 +83,7 @@ class KBService {
85
83
  'Authorization': 'JWT ' + token
86
84
  },
87
85
  method: "POST",
88
- json: json
86
+ json: data
89
87
  }
90
88
  winston.debug("Kb HttpRequest", http_request);
91
89
 
@@ -98,6 +96,28 @@ class KBService {
98
96
  });
99
97
  });
100
98
  }
99
+
100
+ async addAnsweredQuestion(id_project, data, token) {
101
+ return new Promise((resolve, reject) => {
102
+ const http_request = {
103
+ url: API_ENDPOINT + "/" + id_project + "/kb/answered/",
104
+ headers: {
105
+ 'Content-Type': 'application/json',
106
+ 'Authorization': 'JWT ' + token
107
+ },
108
+ json: data,
109
+ method: "POST"
110
+ }
111
+ winston.debug("Kb HttpRequest", http_request);
112
+ httpUtils.request(http_request, (err, response) => {
113
+ if (err) {
114
+ reject(err);
115
+ } else {
116
+ resolve(response);
117
+ }
118
+ });
119
+ });
120
+ }
101
121
  }
102
122
 
103
123
  const kbService = new KBService();
@@ -80,19 +80,14 @@ class DirAddTags {
80
80
  const filled_tags = filler.fill(action.tags, requestVariables);
81
81
  winston.debug("(DirAddTags) filled_tags: ", filled_tags);
82
82
 
83
- console.log("action.tags: ", action.tags);
84
- console.log("filled_tags: ", filled_tags);
85
-
86
83
  /** use case: CONVERSATION */
87
84
  if(target === 'request'){
88
85
 
89
86
  let newTags = filled_tags.split(',').filter(tag => tag !== '').map(el => el.trim())
90
87
  this.logger.native("[Add Tag] Adding following tags to conversation: ", newTags)
91
- console.log("newTags: ", newTags);
92
88
 
93
89
  if(action.pushToList){
94
90
  newTags.forEach(async (tag) => {
95
- console.log("add new tag: ", tag);
96
91
  let tags = await this.addNewTag(tag)
97
92
  if(!tags){
98
93
  callback();
@@ -102,7 +97,6 @@ class DirAddTags {
102
97
  }
103
98
 
104
99
  winston.debug('(DirAddTags) UPDATE request with newTags', newTags)
105
- console.log("update request with newTags: ", newTags);
106
100
  let updatedRequest = await this.updateRequestWithTags(newTags)
107
101
  this.logger.native("[Add Tag] Tags added to conversation")
108
102
  if(!updatedRequest){
@@ -202,9 +196,7 @@ class DirAddTags {
202
196
  return new Promise((resolve) => {
203
197
  let json = []
204
198
  let filteredTags = tags.map((tag) => ({tag: tag, color: '#f0806f'}))
205
- console.log("tags: ", tags);
206
199
  json.push(...filteredTags)
207
- console.log("json: ", json);
208
200
  winston.debug('(httprequest) DirAddTags updateRequestWithTags tags: ', json)
209
201
  const HTTPREQUEST = {
210
202
  url: this.API_ENDPOINT + "/" + this.context.projectId + "/requests/" + this.requestId + '/tag',
@@ -19,6 +19,7 @@ const default_engine = require('../../config/kb/engine');
19
19
  const default_engine_hybrid = require('../../config/kb/engine.hybrid');
20
20
  const default_embedding = require("../../config/kb/embedding");
21
21
  const PromptManager = require('../../config/kb/prompt/rag/PromptManager');
22
+ const { MODELS_MULTIPLIER } = require("../../utils/aiUtils");
22
23
 
23
24
  //const ragPromptManager = new PromptManager(path.join(__dirname, '../../config/kb/prompt/rag'));
24
25
  const ragPromptManager = new PromptManager(path.join(__dirname, '../../config/kb/prompt/rag'));
@@ -95,44 +96,26 @@ class DirAskGPTV2 {
95
96
  callback();
96
97
  return;
97
98
  }
98
-
99
+
99
100
  let trueIntent = action.trueIntent;
100
101
  let falseIntent = action.falseIntent;
101
102
  let trueIntentAttributes = action.trueIntentAttributes;
102
103
  let falseIntentAttributes = action.falseIntentAttributes;
103
-
104
+
104
105
  winston.debug("DirAskGPTV2 trueIntent", trueIntent)
105
106
  winston.debug("DirAskGPTV2 falseIntent", falseIntent)
106
107
  winston.debug("DirAskGPTV2 trueIntentAttributes", trueIntentAttributes)
107
108
  winston.debug("DirAskGPTV2 falseIntentAttributes", falseIntentAttributes)
108
-
109
+
109
110
  // default values
110
111
  let answer = "No answers";
111
- let namespace = this.context.projectId;
112
- let llm = "openai";
113
- let model;
114
- let temperature = 0.7;
115
- let max_tokens = 256;
116
- let top_k = 4;
117
- let alpha;
118
- let transcript;
119
- let citations = false;
120
- let chunks_only = false;
121
- let engine;
122
- let embedding;
123
- let reranking;
124
- let reranking_multiplier;
125
- let skip_unanswered = false;
126
- let source = null;
127
-
128
- if (!action.llm) {
129
- action.llm = "openai";
130
- }
131
-
112
+ action.llm ??= "openai";
113
+ action.model ??= "gpt-4o";
114
+
132
115
  await this.checkMandatoryParameters(action).catch( async (missing_param) => {
133
116
  this.logger.error(`[Ask Knowledge Base] missing attribute '${missing_param}'`);
134
117
  await this.chatbot.addParameter("flowError", `AskKnowledgeBase Error: '${missing_param}' attribute is undefined`);
135
- await this.#assignAttributes(action, answer, source);
118
+ await this.#assignAttributes(action, answer);
136
119
  if (falseIntent) {
137
120
  await this.#executeCondition(false, trueIntent, trueIntentAttributes, falseIntent, falseIntentAttributes);
138
121
  callback(true);
@@ -142,52 +125,35 @@ class DirAskGPTV2 {
142
125
  return Promise.reject();
143
126
  })
144
127
 
145
- if (action.namespace) {
146
- namespace = action.namespace;
147
- }
148
- if (action.llm) {
149
- llm = action.llm;
150
- }
151
- if (action.model) {
152
- model = action.model;
153
- }
154
- if (action.top_k) {
155
- top_k = action.top_k;
156
- }
157
- if (action.temperature) {
158
- temperature = action.temperature;
159
- }
160
- if (action.max_tokens) {
161
- max_tokens = action.max_tokens;
162
- }
163
- if (action.alpha) {
164
- alpha = action.alpha;
165
- }
166
- if (action.citations) {
167
- citations = action.citations;
168
- }
169
- if (action.chunks_only) {
170
- chunks_only = action.chunks_only;
171
- }
172
- if (action.reranking) {
173
- reranking = action.reranking;
174
- }
175
- if (action.reranking_multiplier) {
176
- reranking_multiplier = action.reranking_multiplier;
177
- }
178
- if (action.skip_unanswered) {
179
- skip_unanswered = action.skip_unanswered;
180
- }
128
+ let {
129
+ namespace = this.context.projectId,
130
+ llm,
131
+ model,
132
+ temperature = 0.7,
133
+ max_tokens = 2048,
134
+ top_k = 4,
135
+ alpha = 0.5,
136
+ citations = false,
137
+ chunks_only = false,
138
+ reranking = false,
139
+ reranking_multiplier = 3,
140
+ skip_unanswered = false,
141
+ use_hyde = false,
142
+ use_cache = false,
143
+ } = action;
181
144
 
145
+ let transcript;
146
+
182
147
  let requestVariables = null;
183
148
  requestVariables =
184
- await TiledeskChatbot.allParametersStatic(
185
- this.tdcache, this.requestId
186
- );
187
-
149
+ await TiledeskChatbot.allParametersStatic(
150
+ this.tdcache, this.requestId
151
+ );
152
+
188
153
  const filler = new Filler();
189
154
  const filled_question = filler.fill(action.question, requestVariables);
190
155
  const filled_context = filler.fill(action.context, requestVariables)
156
+
191
157
 
192
158
  if (action.history) {
193
159
  this.logger.native("[Ask Knowledge Base] use chat transcript")
@@ -206,9 +172,10 @@ class DirAskGPTV2 {
206
172
  winston.verbose("DirAskGPT transcript_string is undefined. Skip JSON translation for chat history")
207
173
  }
208
174
  }
209
-
210
- let key;
175
+
211
176
  let publicKey = false;
177
+ let embedding;
178
+ let engine;
212
179
 
213
180
  try {
214
181
  model = await aiController.resolveLLMConfig(this.projectId, llm, model, this.token);
@@ -280,7 +247,7 @@ class DirAskGPTV2 {
280
247
  }
281
248
 
282
249
  let ns;
283
-
250
+
284
251
  if (action.namespaceAsName) {
285
252
  // Namespace could be an attribute
286
253
  const filled_namespace = filler.fill(action.namespace, requestVariables)
@@ -305,7 +272,7 @@ class DirAskGPTV2 {
305
272
  callback();
306
273
  return;
307
274
  }
308
-
275
+
309
276
  if (ns.engine) {
310
277
  engine = ns.engine;
311
278
  } else {
@@ -337,7 +304,7 @@ class DirAskGPTV2 {
337
304
  if (chunks_only) {
338
305
  json.chunks_only = chunks_only;
339
306
  }
340
-
307
+
341
308
  if (ns.hybrid === true) {
342
309
  json.search_type = 'hybrid';
343
310
  json.alpha = alpha;
@@ -398,6 +365,14 @@ class DirAskGPTV2 {
398
365
  json.tags = action.tags;
399
366
  }
400
367
 
368
+ if (use_hyde) {
369
+ json.use_hyde = use_hyde;
370
+ }
371
+
372
+ if (use_cache) {
373
+ json.use_cache = use_cache;
374
+ }
375
+
401
376
  winston.debug("DirAskGPTV2 json:", json);
402
377
 
403
378
  let kb_endpoint = process.env.KB_ENDPOINT_QA;
@@ -426,7 +401,7 @@ class DirAskGPTV2 {
426
401
  data: err.response?.data,
427
402
  });
428
403
  this.logger.error(`[Ask Knowledge Base] Error getting answer`);
429
- await this.#assignAttributes(action, answer, source);
404
+ await this.#assignAttributes(action, answer);
430
405
  if (callback) {
431
406
  if (falseIntent) {
432
407
  await this.#executeCondition(false, trueIntent, trueIntentAttributes, falseIntent, falseIntentAttributes);
@@ -451,15 +426,31 @@ class DirAskGPTV2 {
451
426
 
452
427
  } else {
453
428
  await this.#assignAttributes(action, resbody.answer, resbody.source, resbody.content_chunks);
429
+ let tokens = resbody.prompt_token_size;
454
430
  if (publicKey === true && !chunks_only) {
431
+
455
432
  let tokens_usage = {
456
433
  tokens: resbody.prompt_token_size,
457
434
  model: json.model
458
435
  }
436
+
437
+ let multiplier = MODELS_MULTIPLIER[json.model.name] ?? 1;
438
+ tokens = tokens * multiplier;
459
439
  quotasService.updateQuote(this.projectId, this.token, tokens_usage).catch((err) => {
460
440
  winston.error("Error updating quota: ", err);
461
441
  })
462
442
  }
443
+
444
+ const data = {
445
+ namespace: json.namespace,
446
+ question: json.question,
447
+ answer: resbody.answer,
448
+ request_id: this.requestId,
449
+ tokens: tokens
450
+ }
451
+ kbService.addAnsweredQuestion(this.projectId, data, this.token).catch((err) => {
452
+ winston.error("Error adding answered question: ", err);
453
+ })
463
454
 
464
455
  if (trueIntent) {
465
456
  await this.#executeCondition(true, trueIntent, trueIntentAttributes, falseIntent, falseIntentAttributes);
@@ -471,9 +462,15 @@ class DirAskGPTV2 {
471
462
  }
472
463
  } else {
473
464
  winston.info("DirAskGPTV2 resbody else case: ", resbody);
474
- await this.#assignAttributes(action, answer, source);
465
+ await this.#assignAttributes(action, answer);
475
466
  if (!skip_unanswered) {
476
- kbService.addUnansweredQuestion(this.projectId, json.namespace, json.question, this.token).catch((err) => {
467
+ const data = {
468
+ namespace: json.namespace,
469
+ question: json.question,
470
+ request_id: this.requestId
471
+ }
472
+
473
+ kbService.addUnansweredQuestion(this.projectId, data, this.token).catch((err) => {
477
474
  winston.error("DirAskGPTV2 - Error adding unanswered question: ", {
478
475
  status: err.response?.status,
479
476
  statusText: err.response?.statusText,
@@ -22,7 +22,6 @@ class DirIteration {
22
22
 
23
23
  execute(directive, callback) {
24
24
  winston.verbose("Execute Iteration directive");
25
- console.log("directive: ", directive);
26
25
  let action;
27
26
  if (directive.action) {
28
27
  action = directive.action;
@@ -83,7 +82,6 @@ class DirIteration {
83
82
  */
84
83
  async #initializeIteration(action, actionId, callback) {
85
84
  winston.debug("[Iteration] Initializing iteration state");
86
- console.log("[Iteration] Initializing iteration state");
87
85
 
88
86
  const iterable = action.iterable;
89
87
  const goToIntent = action.goToIntent;
@@ -96,7 +94,6 @@ class DirIteration {
96
94
 
97
95
  if (!iterableValue) {
98
96
  winston.verbose("[Iteration] Iterable object is undefined");
99
- console.log("[Iteration] Iterable object is undefined");
100
97
  this.logger.warn("[Iteration] Iterable object is undefined");
101
98
  callback(true);
102
99
  return;
@@ -107,7 +104,6 @@ class DirIteration {
107
104
 
108
105
  if (!iterableArray) {
109
106
  winston.verbose("[Iteration] Could not convert iterable to array");
110
- console.log("[Iteration] Could not convert iterable to array");
111
107
  this.logger.error(`[Iteration] Could not convert iterable '${iterable}' to array | type: ${typeof iterableValue}`);
112
108
  callback(true);
113
109
  return;
@@ -115,7 +111,6 @@ class DirIteration {
115
111
 
116
112
  if (iterableArray.length === 0) {
117
113
  winston.verbose("[Iteration] Iterable array is empty. Exit...")
118
- console.log("[Iteration] Iterable array is empty. Exit...")
119
114
  this.logger.warn("[Iteration] Iterable array is empty. Exit...")
120
115
  callback(true);
121
116
  return;
@@ -133,7 +128,6 @@ class DirIteration {
133
128
 
134
129
  await this.#saveIterationState(actionId, iterationState);
135
130
  this.logger.native(`[Iteration] Initialized iteration with ${iterableArray.length} items`);
136
- console.log(`[Iteration] Initialized iteration with ${iterableArray.length} items`);
137
131
 
138
132
  // Process first item
139
133
  await this.#processCurrentItem(iterationState, actionId, goToIntent, output, callback);
@@ -141,7 +135,6 @@ class DirIteration {
141
135
 
142
136
  async #continueIteration(iterationState, actionId, callback) {
143
137
  winston.debug(`[Iteration] Continuing iteration from index ${iterationState.currentIndex}`);
144
- console.log(`[Iteration] Continuing iteration from index ${iterationState.currentIndex}`);
145
138
 
146
139
  // Increment index
147
140
  iterationState.currentIndex += 1;
@@ -150,7 +143,6 @@ class DirIteration {
150
143
  if (iterationState.currentIndex >= iterationState.totalItems) {
151
144
  this.logger.native("[Iteration] Iteration completed");
152
145
  await this.#clearIterationState(actionId);
153
- console.log("[Iteration] Iteration completed");
154
146
  callback(false);
155
147
  return;
156
148
  }
@@ -0,0 +1,43 @@
1
+ const winston = require('./winston');
2
+
3
+ // MODELS_MULTIPLIER = {
4
+ // "gpt-3.5-turbo": 0.6,
5
+ // "gpt-4": 25,
6
+ // "gpt-4-turbo-preview": 12
7
+ // }
8
+
9
+ loadMultiplier();
10
+ function loadMultiplier() {
11
+
12
+
13
+ let models_string = process.env.AI_MODELS;
14
+ winston.debug("(loadMultiplier) models_string: ", models_string)
15
+ let models = {};
16
+
17
+ if (!models_string) {
18
+ winston.info("AI_MODELS not defined");
19
+ winston.info("AI Models: ", models)
20
+ return models;
21
+ }
22
+
23
+ let models_string_trimmed = models_string.replace(/ /g,'');
24
+ winston.debug("(loadMultiplier) models_string_trimmed: ", models_string_trimmed)
25
+
26
+ let splitted_string = models_string_trimmed.split(";");
27
+ winston.debug("splitted_string: ", splitted_string)
28
+
29
+ splitted_string.forEach(m => {
30
+ m_split = m.split(":");
31
+ if (!m_split[1]) {
32
+ multiplier = null;
33
+ } else {
34
+ multiplier = Number(m_split[1]);;
35
+ }
36
+ models[m_split[0]] = multiplier;
37
+ })
38
+
39
+ winston.info("AI Models: ", models)
40
+ return models;
41
+ }
42
+
43
+ module.exports = { MODELS_MULTIPLIER: loadMultiplier() }