botium-core 1.14.1 → 1.14.4

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 (39) hide show
  1. package/dist/botium-cjs.js +341 -126
  2. package/dist/botium-cjs.js.map +1 -1
  3. package/dist/botium-es.js +359 -144
  4. package/dist/botium-es.js.map +1 -1
  5. package/package.json +11 -11
  6. package/src/Capabilities.js +2 -0
  7. package/src/scripting/BotiumError.js +40 -3
  8. package/src/scripting/CompilerMarkdown.js +2 -1
  9. package/src/scripting/CompilerTxt.js +1 -4
  10. package/src/scripting/Convo.js +113 -19
  11. package/src/scripting/MatchFunctions.js +30 -8
  12. package/src/scripting/ScriptingMemory.js +7 -0
  13. package/src/scripting/ScriptingProvider.js +87 -36
  14. package/src/scripting/helper.js +3 -2
  15. package/src/scripting/logichook/LogicHookConsts.js +5 -2
  16. package/src/scripting/logichook/LogicHookUtils.js +8 -6
  17. package/src/scripting/logichook/logichooks/ConvoStepParametersLogicHook.js +6 -0
  18. package/src/scripting/logichook/logichooks/OrderedListToButtonLogicHook.js +37 -0
  19. package/test/compiler/compilermarkdown.spec.js +3 -3
  20. package/test/compiler/compilertxt.spec.js +1 -1
  21. package/test/compiler/convos/txt/convos_emptyrow_just_emptyrow.convo.txt +1 -1
  22. package/test/convo/fillAndApplyScriptingMemory.spec.js +11 -0
  23. package/test/logichooks/orderedListToButton.spec.js +35 -0
  24. package/test/scripting/asserters/convoStepParameters.spec.js +151 -0
  25. package/test/scripting/asserters/convos/TEXT_GOOD.convo.txt +6 -0
  26. package/test/scripting/asserters/convos/convo_step_parameter_matchmode_failed.convo.txt +8 -0
  27. package/test/scripting/asserters/convos/convo_step_parameter_matchmode_failed_wer.convo.txt +9 -0
  28. package/test/scripting/asserters/convos/convo_step_parameter_retry_asserters_all_good.convo.txt +9 -0
  29. package/test/scripting/asserters/convos/convo_step_parameter_retry_asserters_botium_timeout.convo.txt +9 -0
  30. package/test/scripting/asserters/convos/convo_step_parameter_retry_asserters_good.convo.txt +9 -0
  31. package/test/scripting/asserters/convos/convo_step_parameter_retry_asserters_good_global.convo.txt +9 -0
  32. package/test/scripting/asserters/convos/convo_step_parameter_retry_main_and_asserter.convo.txt +10 -0
  33. package/test/scripting/asserters/convos/convo_step_parameter_retry_main_botium_timeout.convo.txt +9 -0
  34. package/test/scripting/asserters/convos/convo_step_parameter_retry_main_but_no_button.convo.txt +10 -0
  35. package/test/scripting/asserters/convos/convo_step_parameter_retry_main_good.convo.txt +9 -0
  36. package/test/scripting/asserters/convos/convo_step_parameter_retry_main_good_begin.convo.txt +11 -0
  37. package/test/scripting/logichooks/convos/scripting_memory_overwrite_and_check.convo.txt +2 -2
  38. package/test/scripting/matching/matchingmode.spec.js +4 -1
  39. package/test/scripting/scriptingProvider.spec.js +38 -12
package/dist/botium-es.js CHANGED
@@ -10,7 +10,7 @@ import randomatic from 'randomatic';
10
10
  import lodash from 'lodash';
11
11
  import boolean$1 from 'boolean';
12
12
  import events from 'events';
13
- import debug$n from 'debug';
13
+ import debug$o from 'debug';
14
14
  import isClass from 'is-class';
15
15
  import crypto from 'crypto';
16
16
  import globby from 'globby';
@@ -35,7 +35,7 @@ import express from 'express';
35
35
  import bodyParser from 'body-parser';
36
36
 
37
37
  var name = "botium-core";
38
- var version$1 = "1.14.1";
38
+ var version$1 = "1.14.4";
39
39
  var description = "The Selenium for Chatbots";
40
40
  var main = "index.js";
41
41
  var module = "dist/botium-es.js";
@@ -66,12 +66,12 @@ var bugs = {
66
66
  };
67
67
  var homepage = "https://www.botium.ai";
68
68
  var dependencies = {
69
- "@babel/runtime": "^7.23.2",
69
+ "@babel/runtime": "^7.23.5",
70
70
  async: "^3.2.5",
71
71
  "body-parser": "^1.20.2",
72
72
  boolean: "^3.2.0",
73
73
  bottleneck: "^2.19.5",
74
- "csv-parse": "^5.5.2",
74
+ "csv-parse": "^5.5.3",
75
75
  debug: "^4.3.4",
76
76
  express: "^4.18.2",
77
77
  globby: "11.0.4",
@@ -80,7 +80,7 @@ var dependencies = {
80
80
  "is-json": "^2.0.1",
81
81
  jsonpath: "^1.1.1",
82
82
  lodash: "^4.17.21",
83
- "markdown-it": "^13.0.2",
83
+ "markdown-it": "^14.0.0",
84
84
  "mime-types": "^2.1.35",
85
85
  mkdirp: "^3.0.1",
86
86
  moment: "^2.29.4",
@@ -106,23 +106,23 @@ var dependencies = {
106
106
  yaml: "^2.3.4"
107
107
  };
108
108
  var devDependencies = {
109
- "@babel/core": "^7.23.3",
109
+ "@babel/core": "^7.23.5",
110
110
  "@babel/node": "^7.22.19",
111
- "@babel/plugin-transform-runtime": "^7.23.3",
112
- "@babel/preset-env": "^7.23.3",
111
+ "@babel/plugin-transform-runtime": "^7.23.4",
112
+ "@babel/preset-env": "^7.23.5",
113
113
  chai: "^4.3.10",
114
114
  "chai-as-promised": "^7.1.1",
115
115
  "cross-env": "^7.0.3",
116
- eslint: "^8.53.0",
116
+ eslint: "^8.55.0",
117
117
  "eslint-config-standard": "^17.1.0",
118
118
  "eslint-plugin-import": "^2.29.0",
119
119
  "eslint-plugin-mocha": "^10.2.0",
120
- "eslint-plugin-n": "^16.3.1",
120
+ "eslint-plugin-n": "^16.4.0",
121
121
  "eslint-plugin-promise": "^6.1.1",
122
122
  "eslint-plugin-standard": "^4.1.0",
123
123
  mocha: "^10.2.0",
124
- nock: "^13.3.8",
125
- "npm-check-updates": "^16.14.6",
124
+ nock: "^13.4.0",
125
+ "npm-check-updates": "^16.14.11",
126
126
  nyc: "^15.1.0",
127
127
  rollup: "2.79.1",
128
128
  "rollup-plugin-babel": "^4.4.0",
@@ -325,6 +325,8 @@ var Capabilities = {
325
325
  // varnames, testcasenames
326
326
  SCRIPTING_MEMORY_COLUMN_MODE: 'SCRIPTING_MEMORY_COLUMN_MODE',
327
327
  // Botium Lifecycle Hooks
328
+ SCRIPTING_CONVO_STEP_PARAMETERS: 'SCRIPTING_CONVO_STEP_PARAMETERS',
329
+ // Botium Lifecycle Hooks
328
330
  CUSTOMHOOK_ONBUILD: 'CUSTOMHOOK_ONBUILD',
329
331
  CUSTOMHOOK_ONSTART: 'CUSTOMHOOK_ONSTART',
330
332
  CUSTOMHOOK_ONUSERSAYS: 'CUSTOMHOOK_ONUSERSAYS',
@@ -486,6 +488,7 @@ Capabilities.SCRIPTING_UTTEXPANSION_NAMING_UTTERANCE_MAX;
486
488
  Capabilities.SCRIPTING_MEMORYEXPANSION_KEEP_ORIG;
487
489
  Capabilities.SCRIPTING_MEMORY_MATCHING_MODE;
488
490
  Capabilities.SCRIPTING_MEMORY_COLUMN_MODE;
491
+ Capabilities.SCRIPTING_CONVO_STEP_PARAMETERS;
489
492
  Capabilities.CUSTOMHOOK_ONBUILD;
490
493
  Capabilities.CUSTOMHOOK_ONSTART;
491
494
  Capabilities.CUSTOMHOOK_ONUSERSAYS;
@@ -1034,6 +1037,12 @@ var LogicHookConsts = {
1034
1037
  }, {
1035
1038
  name: 'CONDITIONAL_STEP_JSON_PATH_BASED',
1036
1039
  className: 'ConditionalJsonPathBasedLogicHook.js'
1040
+ }, {
1041
+ name: 'CONVO_STEP_PARAMETERS',
1042
+ className: 'ConvoStepParametersLogicHook.js'
1043
+ }, {
1044
+ name: 'ORDERED_LIST_TO_BUTTON',
1045
+ className: 'OrderedListToButtonLogicHook'
1037
1046
  }],
1038
1047
  DEFAULT_USER_INPUTS: [{
1039
1048
  name: 'BUTTON',
@@ -1044,14 +1053,16 @@ var LogicHookConsts = {
1044
1053
  }, {
1045
1054
  name: 'FORM',
1046
1055
  className: 'FormInput'
1047
- }]
1056
+ }],
1057
+ LOGIC_HOOK_EVENTS: ['onConvoBegin', 'onMeStart', 'onMePrepare', 'onMeEnd', 'onBotStart', 'onBotEnd', 'onBotPrepare', 'onConvoEnd']
1048
1058
  };
1049
1059
  LogicHookConsts.LOGIC_HOOK_INCLUDE;
1050
1060
  LogicHookConsts.DEFAULT_ASSERTERS;
1051
1061
  LogicHookConsts.DEFAULT_LOGIC_HOOKS;
1052
1062
  LogicHookConsts.DEFAULT_USER_INPUTS;
1063
+ LogicHookConsts.LOGIC_HOOK_EVENTS;
1053
1064
 
1054
- const debug$m = debug$n('botium-core-asserterUtils');
1065
+ const debug$n = debug$o('botium-core-asserterUtils');
1055
1066
  const {
1056
1067
  DEFAULT_ASSERTERS,
1057
1068
  DEFAULT_LOGIC_HOOKS,
@@ -1103,7 +1114,7 @@ var LogicHookUtils_1 = class LogicHookUtils {
1103
1114
  _fetchAsserters() {
1104
1115
  this.caps[Capabilities.ASSERTERS].forEach(asserter => {
1105
1116
  if (this.asserters[asserter.ref]) {
1106
- debug$m(`${asserter.ref} asserter already exists, overwriting.`);
1117
+ debug$n(`${asserter.ref} asserter already exists, overwriting.`);
1107
1118
  }
1108
1119
  this.asserters[asserter.ref] = this._loadClass(asserter, 'asserter');
1109
1120
  if (asserter.global) {
@@ -1114,7 +1125,7 @@ var LogicHookUtils_1 = class LogicHookUtils {
1114
1125
  _fetchLogicHooks() {
1115
1126
  this.caps[Capabilities.LOGIC_HOOKS].forEach(logicHook => {
1116
1127
  if (this.logicHooks[logicHook.ref]) {
1117
- debug$m(`${logicHook.ref} logic hook already exists, overwriting.`);
1128
+ debug$n(`${logicHook.ref} logic hook already exists, overwriting.`);
1118
1129
  }
1119
1130
  this.logicHooks[logicHook.ref] = this._loadClass(logicHook, 'logichook');
1120
1131
  if (logicHook.global) {
@@ -1125,7 +1136,7 @@ var LogicHookUtils_1 = class LogicHookUtils {
1125
1136
  _fetchUserInputs() {
1126
1137
  this.caps[Capabilities.USER_INPUTS].forEach(userInput => {
1127
1138
  if (this.userInputs[userInput.ref]) {
1128
- debug$m(`${userInput.ref} userinput already exists, overwriting.`);
1139
+ debug$n(`${userInput.ref} userinput already exists, overwriting.`);
1129
1140
  }
1130
1141
  this.userInputs[userInput.ref] = this._loadClass(userInput, 'userinput');
1131
1142
  });
@@ -1200,6 +1211,7 @@ var LogicHookUtils_1 = class LogicHookUtils {
1200
1211
  throw new Error(`Logic Hook specification ${ref} ${hookType} (${packageName}) invalid: ${err.message}`);
1201
1212
  }
1202
1213
  }
1214
+ const typeAsText = hookType === 'asserter' ? 'Asserter' : hookType === 'logichook' ? 'Logic Hook' : hookType === 'userinput' ? 'User Input' : 'Unknown';
1203
1215
  if (isClass(src)) {
1204
1216
  try {
1205
1217
  const CheckClass = src;
@@ -1208,7 +1220,7 @@ var LogicHookUtils_1 = class LogicHookUtils {
1208
1220
  ...this.buildScriptContext
1209
1221
  }, this.caps, args);
1210
1222
  } catch (err) {
1211
- throw new Error(`Logic Hook specification ${ref} from class invalid: ${err.message}`);
1223
+ throw new Error(`${typeAsText} specification ${ref} from class invalid: ${err.message}`);
1212
1224
  }
1213
1225
  }
1214
1226
  if (lodash.isFunction(src)) {
@@ -1218,7 +1230,7 @@ var LogicHookUtils_1 = class LogicHookUtils {
1218
1230
  ...this.buildScriptContext
1219
1231
  }, this.caps, args);
1220
1232
  } catch (err) {
1221
- throw new Error(`Logic Hook specification ${ref} from function invalid: ${err.message}`);
1233
+ throw new Error(`${typeAsText} specification ${ref} from function invalid: ${err.message}`);
1222
1234
  }
1223
1235
  }
1224
1236
  if (lodash.isObject(src) && !lodash.isString(src)) {
@@ -1236,7 +1248,7 @@ var LogicHookUtils_1 = class LogicHookUtils {
1236
1248
  }, {});
1237
1249
  return hookObject;
1238
1250
  } catch (err) {
1239
- throw new Error(`Logic Hook specification ${ref} ${hookType} from provided src (${util.inspect(src)}) invalid: ${err.message}`);
1251
+ throw new Error(`${typeAsText} specification ${ref} ${hookType} from provided src (${util.inspect(src)}) invalid: ${err.message}`);
1240
1252
  }
1241
1253
  }
1242
1254
  if (lodash.isString(src)) {
@@ -1297,7 +1309,7 @@ var LogicHookUtils_1 = class LogicHookUtils {
1297
1309
  try {
1298
1310
  return tryLoadFromSource(tryLoadFile, tryLoad.tryLoadAsserterByName);
1299
1311
  } catch (err) {
1300
- loadErr.push(`Logic Hook specification ${ref} ${hookType} from "${src}" invalid: ${err.message} `);
1312
+ loadErr.push(`${typeAsText} specification ${ref} ${hookType} from "${src}" invalid: ${err.message} `);
1301
1313
  }
1302
1314
  }
1303
1315
  }
@@ -1306,13 +1318,13 @@ var LogicHookUtils_1 = class LogicHookUtils {
1306
1318
  try {
1307
1319
  return tryLoadFromSource(tryLoad.tryLoadPackageName, tryLoad.tryLoadAsserterByName);
1308
1320
  } catch (err) {
1309
- loadErr.push(`Logic Hook specification ${ref} ${hookType} from "${src}" invalid: ${err.message} `);
1321
+ loadErr.push(`${typeAsText} specification ${ref} ${hookType} from "${src}" invalid: ${err.message} `);
1310
1322
  }
1311
1323
  }
1312
1324
  }
1313
- loadErr.forEach(debug$m);
1325
+ loadErr.forEach(debug$n);
1314
1326
  }
1315
- throw new Error(`Logic Hook specification ${ref} ${hookType} from "${util.inspect(src)}" invalid : no loader available`);
1327
+ throw new Error(`${typeAsText} specification ${ref} ${hookType} from "${util.inspect(src)}" invalid : no loader available`);
1316
1328
  }
1317
1329
  };
1318
1330
 
@@ -1521,10 +1533,11 @@ var Enums = {
1521
1533
  };
1522
1534
  Enums.E_SCRIPTING_MEMORY_COLUMN_MODE;
1523
1535
 
1524
- const debug$l = debug$n('botium-core-scripting-helper');
1536
+ const debug$m = debug$o('botium-core-scripting-helper');
1525
1537
  const {
1526
1538
  E_SCRIPTING_MEMORY_COLUMN_MODE: E_SCRIPTING_MEMORY_COLUMN_MODE$1
1527
1539
  } = Enums;
1540
+ const WHITE_SPACES_EXCEPT_SPACE_CHAR_AT_THE_END = /[\n\t\r]+$/;
1528
1541
  const normalizeText$1 = (str, doCleanup) => {
1529
1542
  if (str && lodash.isArray(str)) {
1530
1543
  str = str.join(' ');
@@ -1766,7 +1779,7 @@ const linesToConvoStep$5 = (lines, sender, context, eol, singleLineMode = false)
1766
1779
  if (eol === null) {
1767
1780
  throw new Error('eol cant be null');
1768
1781
  }
1769
- convoStep.messageText = textLines.join(eol).trim();
1782
+ convoStep.messageText = textLines.join(eol).replace(WHITE_SPACES_EXCEPT_SPACE_CHAR_AT_THE_END, '');
1770
1783
  }
1771
1784
  }
1772
1785
  } else {
@@ -1983,7 +1996,7 @@ const convoStepToLines$2 = step => {
1983
1996
  lines.push(logicHook.name + _formatAppendArgs(logicHook.args));
1984
1997
  });
1985
1998
  }
1986
- return lines.map(l => l.trim());
1999
+ return lines;
1987
2000
  };
1988
2001
  const linesToScriptingMemories$2 = (lines, columnMode = null) => {
1989
2002
  const guessScriptingMemoryColumnMode = lines => {
@@ -2097,7 +2110,7 @@ const calculateWer$2 = (str, pattern) => {
2097
2110
  errCount += err.filter(err => err === true).length;
2098
2111
  allCount += err.length;
2099
2112
  }
2100
- debug$l(`Word Error Rate Asserter - Compared Bot Message '${botMessage}' / '${utt}': ${(errCount / allCount).toFixed(2)}`);
2113
+ debug$m(`Word Error Rate Asserter - Compared Bot Message '${botMessage}' / '${utt}': ${(errCount / allCount).toFixed(2)}`);
2101
2114
  return (errCount / allCount).toFixed(2);
2102
2115
  };
2103
2116
  const toPercent$1 = s => `${(s * 100).toFixed(0)}%`;
@@ -2205,6 +2218,44 @@ const BotiumError$4 = class BotiumError extends Error {
2205
2218
  return null;
2206
2219
  }
2207
2220
  }
2221
+ hasError({
2222
+ type,
2223
+ source
2224
+ }) {
2225
+ if (this.context) {
2226
+ const errArr = lodash.isArray(this.context) ? this.context : [this.context];
2227
+ for (const err of errArr) {
2228
+ if (err.type === 'list') {
2229
+ for (const internal of err.errors) {
2230
+ if ((!type || internal.type === type) && (!source || internal.source === source)) {
2231
+ return true;
2232
+ }
2233
+ }
2234
+ }
2235
+ if ((!type || err.type === type) && (!source || err.source === source)) {
2236
+ return true;
2237
+ }
2238
+ }
2239
+ } else {
2240
+ return false;
2241
+ }
2242
+ }
2243
+ toArray() {
2244
+ if (this.context) {
2245
+ let result = [];
2246
+ const errArr = lodash.isArray(this.context) ? this.context : [this.context];
2247
+ for (const err of errArr) {
2248
+ if (err.type === 'list') {
2249
+ result = result.concat(err.errors);
2250
+ } else {
2251
+ result.push(err);
2252
+ }
2253
+ }
2254
+ return result;
2255
+ } else {
2256
+ return [];
2257
+ }
2258
+ }
2208
2259
  };
2209
2260
  const _getChildErrorsFromContext = context => {
2210
2261
  if (context && context.errors && lodash.isArray(context.errors)) {
@@ -2212,12 +2263,16 @@ const _getChildErrorsFromContext = context => {
2212
2263
  }
2213
2264
  return false;
2214
2265
  };
2215
- const botiumErrorFromErr$2 = (message, err) => {
2266
+ const botiumErrorFromErr$2 = (message, err, context = {}) => {
2216
2267
  if (err instanceof BotiumError$4) {
2217
- return new BotiumError$4(message, err.context, true);
2268
+ return new BotiumError$4(message, {
2269
+ ...err.context,
2270
+ ...context
2271
+ }, true);
2218
2272
  } else {
2219
2273
  return new BotiumError$4(message, {
2220
- err
2274
+ err,
2275
+ ...context
2221
2276
  }, true);
2222
2277
  }
2223
2278
  };
@@ -2253,7 +2308,7 @@ var BotiumError_1 = {
2253
2308
  botiumErrorFromList: botiumErrorFromList$2
2254
2309
  };
2255
2310
 
2256
- const debug$k = debug$n('botium-core-ScriptingMemory');
2311
+ const debug$l = debug$o('botium-core-ScriptingMemory');
2257
2312
  const {
2258
2313
  v1: uuidv1
2259
2314
  } = uuid;
@@ -2492,6 +2547,13 @@ const _apply = (scriptingMemory, str, caps, mockMsg) => {
2492
2547
  return arg;
2493
2548
  }
2494
2549
  });
2550
+ args = args.map(arg => {
2551
+ const argStr = `${arg}`;
2552
+ if (argStr.startsWith('$')) {
2553
+ return scriptingMemory[argStr.substring(1)] || arg;
2554
+ }
2555
+ return arg;
2556
+ });
2495
2557
  str = str.replace(match, SCRIPTING_FUNCTIONS$1[key].handler(caps, ...args, mockMsg));
2496
2558
  } else {
2497
2559
  str = str.replace(match, SCRIPTING_FUNCTIONS$1[key].handler(caps));
@@ -2506,7 +2568,7 @@ const extractVarNames = text => {
2506
2568
  return (lodash.isString(text) ? text.match(/\$[A-Za-z]\w+/g) : false) || [];
2507
2569
  };
2508
2570
  const fill = (container, scriptingMemory, result, utterance, scriptingEvents) => {
2509
- debug$k(`fill start: ${util.inspect(scriptingMemory)}`);
2571
+ debug$l(`fill start: ${util.inspect(scriptingMemory)}`);
2510
2572
  let varRegex;
2511
2573
  switch (container.caps[Capabilities.SCRIPTING_MEMORY_MATCHING_MODE]) {
2512
2574
  case 'word':
@@ -2540,14 +2602,14 @@ const fill = (container, scriptingMemory, result, utterance, scriptingEvents) =>
2540
2602
  if (i <= varMatches.length) {
2541
2603
  const varName = varMatches[i - 1];
2542
2604
  if (RESERVED_WORDS.indexOf(varName) >= 0) {
2543
- debug$k(`fill Variable "${varName}" is not overwritten, because it is reserved word. `);
2605
+ debug$l(`fill Variable "${varName}" is not overwritten, because it is reserved word. `);
2544
2606
  } else {
2545
2607
  scriptingMemory[varName] = resultMatches[i];
2546
2608
  }
2547
2609
  }
2548
2610
  }
2549
2611
  });
2550
- debug$k(`fill end: ${util.inspect(scriptingMemory)}`);
2612
+ debug$l(`fill end: ${util.inspect(scriptingMemory)}`);
2551
2613
  }
2552
2614
  };
2553
2615
  var ScriptingMemory = {
@@ -2565,7 +2627,7 @@ ScriptingMemory.extractVarNames;
2565
2627
  ScriptingMemory.RESERVED_WORDS;
2566
2628
  ScriptingMemory.SCRIPTING_FUNCTIONS;
2567
2629
 
2568
- const debug$j = debug$n('botium-core-Convo');
2630
+ const debug$k = debug$o('botium-core-Convo');
2569
2631
  const {
2570
2632
  BotiumError: BotiumError$2,
2571
2633
  botiumErrorFromErr: botiumErrorFromErr$1,
@@ -2719,10 +2781,10 @@ class TranscriptError extends Error {
2719
2781
  class Convo$6 {
2720
2782
  constructor(context, fromJson = {}) {
2721
2783
  if (fromJson instanceof Convo$6) {
2722
- debug$j('Illegal state!!! Parameter should be a JSON, but it is a Convo');
2784
+ debug$k('Illegal state!!! Parameter should be a JSON, but it is a Convo');
2723
2785
  } else if (fromJson.beginAsserter) {
2724
2786
  // beginAsserter is one of the fields which are lost
2725
- debug$j('Illegal state!!! Parameter should be a native JSON, but looks as a Convo converted to JSON');
2787
+ debug$k('Illegal state!!! Parameter should be a native JSON, but looks as a Convo converted to JSON');
2726
2788
  }
2727
2789
  this.scriptingEvents = context.scriptingEvents;
2728
2790
  this.context = context;
@@ -2871,8 +2933,52 @@ class Convo$6 {
2871
2933
  let skipTranscriptStep = false;
2872
2934
  let conditionalGroupId = null;
2873
2935
  let conditionMetInGroup = false;
2874
- for (let i = 0; i < this.conversation.length; i++) {
2936
+ let globalConvoStepParameters = container.caps[Capabilities.SCRIPTING_CONVO_STEP_PARAMETERS] || {};
2937
+ let retryBotMessageTimeoutEnd = null;
2938
+ let retryBotMessageConvoId = null;
2939
+ let retryBotMessageDropBotResponse = false;
2940
+ for (let i = 0; i < this.conversation.length; i = retryBotMessageDropBotResponse ? i : i + 1) {
2941
+ retryBotMessageDropBotResponse = false;
2875
2942
  const convoStep = this.conversation[i];
2943
+ const rawConvoStepParameters = convoStep.logicHooks.find(lh => lh.name === 'CONVO_STEP_PARAMETERS')?.args;
2944
+ let convoStepParameters = {};
2945
+ if (rawConvoStepParameters && rawConvoStepParameters.length) {
2946
+ let params;
2947
+ if (rawConvoStepParameters[0].trim().startsWith('{')) {
2948
+ try {
2949
+ params = JSON.parse(rawConvoStepParameters[0]);
2950
+ } catch (e) {
2951
+ debug$k(`${this.header.name}/${convoStep.stepTag}: Failed to parse convo step parameters from JSON ${rawConvoStepParameters[0]}`);
2952
+ }
2953
+ }
2954
+ if (!params || !Object.keys(params).length) {
2955
+ params = {};
2956
+ for (const param of rawConvoStepParameters) {
2957
+ const semicolon = param.indexOf(':');
2958
+ if (semicolon) {
2959
+ try {
2960
+ const name = param.substring(0, semicolon);
2961
+ const value = param.substring(semicolon + 1);
2962
+ params[name] = value;
2963
+ } catch (e) {
2964
+ debug$k(`${this.header.name}/${convoStep.stepTag}: Failed to parse convo step parameter from arg ${param}`);
2965
+ }
2966
+ }
2967
+ }
2968
+ }
2969
+ if (convoStep.sender === 'begin') {
2970
+ globalConvoStepParameters = Object.assign({}, globalConvoStepParameters || {}, params);
2971
+ } else {
2972
+ convoStepParameters = Object.assign({}, globalConvoStepParameters || {}, params);
2973
+ }
2974
+ } else {
2975
+ if (convoStep.sender !== 'begin') {
2976
+ convoStepParameters = globalConvoStepParameters;
2977
+ }
2978
+ }
2979
+ if (Object.keys(convoStepParameters).length) {
2980
+ debug$k(`${this.header.name}: using convo step parameters ${JSON.stringify(convoStepParameters)}`);
2981
+ }
2876
2982
  const currentStepIndex = i;
2877
2983
  container.eventEmitter.emit(Events.CONVO_STEP_NEXT, container, convoStep, i);
2878
2984
  skipTranscriptStep = false;
@@ -2934,10 +3040,10 @@ class Convo$6 {
2934
3040
  });
2935
3041
  await this._checkBotRepliesConsumed(container);
2936
3042
  const coreMsg = lodash.omit(removeBuffers(meMsg), ['sourceData']);
2937
- debug$j(`${this.header.name}/${convoStep.stepTag}: user says (cleaned by binary and base64 data and sourceData) ${JSON.stringify(coreMsg, null, 2)}`);
3043
+ debug$k(`${this.header.name}/${convoStep.stepTag}: user says (cleaned by binary and base64 data and sourceData) ${JSON.stringify(coreMsg, null, 2)}`);
2938
3044
  await new Promise(resolve => {
2939
- if (container.caps.SIMULATE_WRITING_SPEED && meMsg.messageText && meMsg.messageText.length) {
2940
- setTimeout(() => resolve(), container.caps.SIMULATE_WRITING_SPEED * meMsg.messageText.length);
3045
+ if (container.caps[Capabilities.SIMULATE_WRITING_SPEED] && meMsg.messageText && meMsg.messageText.length) {
3046
+ setTimeout(() => resolve(), container.caps[Capabilities.SIMULATE_WRITING_SPEED] * meMsg.messageText.length);
2941
3047
  } else {
2942
3048
  resolve();
2943
3049
  }
@@ -2970,7 +3076,7 @@ class Convo$6 {
2970
3076
  });
2971
3077
  continue;
2972
3078
  } else {
2973
- debug$j(`${this.header.name}/${convoStep.stepTag}: message not found in #me section, message not sent to container ${util.inspect(convoStep)}`);
3079
+ debug$k(`${this.header.name}/${convoStep.stepTag}: message not found in #me section, message not sent to container ${util.inspect(convoStep)}`);
2974
3080
  transcriptStep.botEnd = new Date();
2975
3081
  await this.scriptingEvents.onMeEnd({
2976
3082
  convo: this,
@@ -2986,7 +3092,7 @@ class Convo$6 {
2986
3092
  } catch (err) {
2987
3093
  transcriptStep.botEnd = new Date();
2988
3094
  const failErr = botiumErrorFromErr$1(`${this.header.name}/${convoStep.stepTag}: error sending to bot - ${err.message || err}`, err);
2989
- debug$j(failErr);
3095
+ debug$k(failErr);
2990
3096
  try {
2991
3097
  this.scriptingEvents.fail && this.scriptingEvents.fail(failErr);
2992
3098
  } catch (failErr) {}
@@ -2999,7 +3105,7 @@ class Convo$6 {
2999
3105
  waitForBotSays = true;
3000
3106
  }
3001
3107
  try {
3002
- debug$j(`${this.header.name} wait for bot ${convoStep.channel || ''}`);
3108
+ debug$k(`${this.header.name} wait for bot ${convoStep.channel || ''}`);
3003
3109
  await this.scriptingEvents.onBotStart({
3004
3110
  convo: this,
3005
3111
  convoStep,
@@ -3015,11 +3121,11 @@ class Convo$6 {
3015
3121
  transcriptStep.botEnd = new Date();
3016
3122
  transcriptStep.actual = new BotiumMockMessage_1(botMsg);
3017
3123
  const coreMsg = lodash.omit(removeBuffers(botMsg), ['sourceData']);
3018
- debug$j(`${this.header.name}: bot says (cleaned by binary and base64 data and sourceData) ${JSON.stringify(coreMsg, null, 2)}`);
3124
+ debug$k(`${this.header.name}: bot says (cleaned by binary and base64 data and sourceData) ${JSON.stringify(coreMsg, null, 2)}`);
3019
3125
  } catch (err) {
3020
3126
  transcriptStep.botEnd = new Date();
3021
3127
  const failErr = botiumErrorFromErr$1(`${this.header.name}/${convoStep.stepTag}: error waiting for bot - ${err.message}`, err);
3022
- debug$j(failErr);
3128
+ debug$k(failErr);
3023
3129
  try {
3024
3130
  this.scriptingEvents.fail && this.scriptingEvents.fail(failErr, lastMeConvoStep);
3025
3131
  } catch (failErr) {}
@@ -3038,11 +3144,11 @@ class Convo$6 {
3038
3144
  if (prepared) {
3039
3145
  transcriptStep.actual = new BotiumMockMessage_1(botMsg);
3040
3146
  const coreMsg = lodash.omit(removeBuffers(botMsg), ['sourceData']);
3041
- debug$j(`${this.header.name}: onBotPrepare (cleaned by binary and base64 data and sourceData) ${JSON.stringify(coreMsg, null, 2)}`);
3147
+ debug$k(`${this.header.name}: onBotPrepare (cleaned by binary and base64 data and sourceData) ${JSON.stringify(coreMsg, null, 2)}`);
3042
3148
  }
3043
3149
  } catch (err) {
3044
3150
  const failErr = botiumErrorFromErr$1(`${this.header.name}/${convoStep.stepTag}: onBotPrepare error - ${err.message || err}`, err);
3045
- debug$j(failErr);
3151
+ debug$k(failErr);
3046
3152
  try {
3047
3153
  this.scriptingEvents.fail && this.scriptingEvents.fail(failErr, lastMeConvoStep);
3048
3154
  } catch (failErr) {}
@@ -3063,7 +3169,7 @@ class Convo$6 {
3063
3169
  skipTranscriptStep = true;
3064
3170
  if (endOfConditionalGroup && !conditionMetInGroup && !convoStep.optional) {
3065
3171
  const failErr = new BotiumError$2(`${this.header.name}/${convoStep.stepTag}: Non of the conditions are met in ${conditionalGroupId ? `'${conditionalGroupId}' ` : ''}condition group`);
3066
- debug$j(failErr);
3172
+ debug$k(failErr);
3067
3173
  throw failErr;
3068
3174
  }
3069
3175
  if (endOfConditionalGroup) {
@@ -3083,7 +3189,7 @@ class Convo$6 {
3083
3189
  }
3084
3190
  if (!botMsg || !botMsg.messageText && !botMsg.media && !botMsg.buttons && !botMsg.cards && !botMsg.sourceData && !botMsg.nlp) {
3085
3191
  const failErr = new BotiumError$2(`${this.header.name}/${convoStep.stepTag}: bot says nothing`);
3086
- debug$j(failErr);
3192
+ debug$k(failErr);
3087
3193
  try {
3088
3194
  this.scriptingEvents.fail && this.scriptingEvents.fail(failErr, lastMeConvoStep);
3089
3195
  } catch (failErr) {}
@@ -3091,10 +3197,29 @@ class Convo$6 {
3091
3197
  }
3092
3198
  const isErrorHandledWithOptionConvoStep = err => {
3093
3199
  const nextConvoStep = this.conversation[i + 1];
3200
+ const retryConfig = convoStepParameters?.ignoreNotMatchedBotResponses;
3201
+ const retryOn = convoStep.sender === 'bot' && retryConfig && retryConfig.timeout && retryConfig.mainAsserter;
3094
3202
  if (convoStep.optional && nextConvoStep && nextConvoStep.sender === 'bot') {
3203
+ if (retryOn) {
3204
+ debug$k(`${this.header.name}/${convoStep.stepTag}: Retry failed asserter is ignored on optional convo`);
3205
+ }
3095
3206
  waitForBotSays = false;
3096
3207
  skipTranscriptStep = true;
3097
3208
  return true;
3209
+ } else if (retryOn) {
3210
+ if (!retryBotMessageTimeoutEnd || retryBotMessageConvoId !== convoStep.stepTag) {
3211
+ retryBotMessageTimeoutEnd = transcriptStep.stepBegin.getTime() + +retryConfig.timeout;
3212
+ retryBotMessageConvoId = convoStep.stepTag;
3213
+ }
3214
+ const now = new Date().getTime();
3215
+ const timeoutRemaining = retryBotMessageTimeoutEnd - now;
3216
+ if (timeoutRemaining > 0) {
3217
+ debug$k(`${this.header.name}/${convoStep.stepTag}: Convo step retry on, timeout remaining: ${timeoutRemaining}, error: "${err.message}"`);
3218
+ retryBotMessageDropBotResponse = true;
3219
+ return false;
3220
+ } else {
3221
+ debug$k(`${this.header.name}/${convoStep.stepTag}: Convo step retry on, but timeout is over. error: "${err.message}"`);
3222
+ }
3098
3223
  }
3099
3224
  if (container.caps[Capabilities.SCRIPTING_ENABLE_MULTIPLE_ASSERT_ERRORS]) {
3100
3225
  assertErrors.push(err);
@@ -3112,7 +3237,7 @@ class Convo$6 {
3112
3237
  const tomatch = this._resolveUtterancesToMatch(container, Object.assign({}, scriptingMemoryUpdate, scriptingMemory), messageText, botMsg);
3113
3238
  if (convoStep.not) {
3114
3239
  try {
3115
- this.scriptingEvents.assertBotNotResponse(response, tomatch, `${this.header.name}/${convoStep.stepTag}`, lastMeConvoStep);
3240
+ this.scriptingEvents.assertBotNotResponse(response, tomatch, `${this.header.name}/${convoStep.stepTag}`, lastMeConvoStep, convoStepParameters);
3116
3241
  } catch (err) {
3117
3242
  if (isErrorHandledWithOptionConvoStep(err)) {
3118
3243
  continue;
@@ -3120,7 +3245,7 @@ class Convo$6 {
3120
3245
  }
3121
3246
  } else {
3122
3247
  try {
3123
- this.scriptingEvents.assertBotResponse(response, tomatch, `${this.header.name}/${convoStep.stepTag}`, lastMeConvoStep);
3248
+ this.scriptingEvents.assertBotResponse(response, tomatch, `${this.header.name}/${convoStep.stepTag}`, lastMeConvoStep, convoStepParameters);
3124
3249
  } catch (err) {
3125
3250
  if (isErrorHandledWithOptionConvoStep(err)) {
3126
3251
  continue;
@@ -3129,7 +3254,7 @@ class Convo$6 {
3129
3254
  }
3130
3255
  } else if (convoStep.sourceData) {
3131
3256
  try {
3132
- this._compareObject(container, scriptingMemory, convoStep, botMsg.sourceData, convoStep.sourceData, botMsg);
3257
+ this._compareObject(container, scriptingMemory, convoStep, botMsg.sourceData, convoStep.sourceData, botMsg, convoStepParameters);
3133
3258
  } catch (err) {
3134
3259
  if (isErrorHandledWithOptionConvoStep(err)) {
3135
3260
  continue;
@@ -3163,19 +3288,42 @@ class Convo$6 {
3163
3288
  skipTranscriptStep = true;
3164
3289
  continue;
3165
3290
  }
3166
- const failErr = botiumErrorFromErr$1(`${this.header.name}/${convoStep.stepTag}: assertion error - ${err.message || err}`, err);
3167
- debug$j(failErr);
3168
- try {
3169
- this.scriptingEvents.fail && this.scriptingEvents.fail(failErr, lastMeConvoStep);
3170
- } catch (failErr) {}
3171
- if (container.caps[Capabilities.SCRIPTING_ENABLE_MULTIPLE_ASSERT_ERRORS] && err instanceof BotiumError$2) {
3172
- assertErrors.push(err);
3291
+ const errors = err.toArray ? err.toArray() : [];
3292
+ const retryConfig = convoStepParameters?.ignoreNotMatchedBotResponses;
3293
+ const retryOn = convoStep.sender === 'bot' && retryConfig && retryConfig.timeout && errors.length && errors.filter(({
3294
+ type,
3295
+ source,
3296
+ asserter
3297
+ }) => type === 'asserter' && (retryConfig.allAsserters || retryConfig.asserters && retryConfig.asserters.includes(asserter))).length;
3298
+ if (retryOn && (!retryBotMessageTimeoutEnd || retryBotMessageConvoId !== convoStep.stepTag)) {
3299
+ retryBotMessageTimeoutEnd = transcriptStep.stepBegin.getTime() + +retryConfig.timeout;
3300
+ retryBotMessageConvoId = convoStep.stepTag;
3301
+ }
3302
+ const now = new Date().getTime();
3303
+ const timeoutRemaining = retryOn && retryBotMessageTimeoutEnd - now;
3304
+ if (retryOn && timeoutRemaining > 0) {
3305
+ debug$k(`${this.header.name}/${convoStep.stepTag}: Convo step retry on, timeout remaining: ${timeoutRemaining}, error: "${err.message}"`);
3306
+ retryBotMessageDropBotResponse = true;
3173
3307
  } else {
3174
- throw failErr;
3308
+ if (retryOn && timeoutRemaining <= 0) {
3309
+ debug$k(`${this.header.name}/${convoStep.stepTag}: Convo step retry on, but timeout is over. error: "${err.message}"`);
3310
+ }
3311
+ const failErr = botiumErrorFromErr$1(`${this.header.name}/${convoStep.stepTag}: assertion error - ${err.message || err}`, err);
3312
+ debug$k(failErr);
3313
+ try {
3314
+ this.scriptingEvents.fail && this.scriptingEvents.fail(failErr, lastMeConvoStep);
3315
+ } catch (failErr) {}
3316
+ if (container.caps[Capabilities.SCRIPTING_ENABLE_MULTIPLE_ASSERT_ERRORS] && err instanceof BotiumError$2) {
3317
+ assertErrors.push(err);
3318
+ } else {
3319
+ throw failErr;
3320
+ }
3175
3321
  }
3176
3322
  }
3177
3323
  if (container.caps[Capabilities.SCRIPTING_ENABLE_MULTIPLE_ASSERT_ERRORS]) {
3178
3324
  if (assertErrors.length > 0) {
3325
+ // this has no effect, but logically it has to be false
3326
+ retryBotMessageDropBotResponse = false;
3179
3327
  throw botiumErrorFromList$1(assertErrors, {});
3180
3328
  }
3181
3329
  } else {
@@ -3185,7 +3333,7 @@ class Convo$6 {
3185
3333
  }
3186
3334
  } else {
3187
3335
  const failErr = new BotiumError$2(`${this.header.name}/${convoStep.stepTag}: invalid sender - ${util.inspect(convoStep.sender)}`);
3188
- debug$j(failErr);
3336
+ debug$k(failErr);
3189
3337
  try {
3190
3338
  this.scriptingEvents.fail && this.scriptingEvents.fail(failErr);
3191
3339
  } catch (failErr) {}
@@ -3235,7 +3383,7 @@ class Convo$6 {
3235
3383
  }
3236
3384
  }
3237
3385
  }
3238
- _compareObject(container, scriptingMemory, convoStep, result, expected, botMsg) {
3386
+ _compareObject(container, scriptingMemory, convoStep, result, expected, botMsg, convoStepParameters) {
3239
3387
  if (expected === null || expected === undefined) return;
3240
3388
  if (lodash.isArray(expected)) {
3241
3389
  if (!lodash.isArray(result)) {
@@ -3245,12 +3393,12 @@ class Convo$6 {
3245
3393
  throw new BotiumError$2(`${this.header.name}/${convoStep.stepTag}: bot response expected array length ${expected.length}, got ${result.length}`);
3246
3394
  }
3247
3395
  for (let i = 0; i < expected.length; i++) {
3248
- this._compareObject(container, scriptingMemory, convoStep, result[i], expected[i]);
3396
+ this._compareObject(container, scriptingMemory, convoStep, result[i], expected[i], null, convoStepParameters);
3249
3397
  }
3250
3398
  } else if (lodash.isObject(expected)) {
3251
3399
  lodash.forOwn(expected, (value, key) => {
3252
3400
  if (Object.prototype.hasOwnProperty.call(result, key)) {
3253
- this._compareObject(container, scriptingMemory, convoStep, result[key], expected[key]);
3401
+ this._compareObject(container, scriptingMemory, convoStep, result[key], expected[key], null, convoStepParameters);
3254
3402
  } else {
3255
3403
  throw new BotiumError$2(`${this.header.name}/${convoStep.stepTag}: bot response "${result}" missing expected property: ${key}`);
3256
3404
  }
@@ -3259,7 +3407,7 @@ class Convo$6 {
3259
3407
  ScriptingMemory.fill(container, scriptingMemory, result, expected, this.scriptingEvents);
3260
3408
  const response = this._checkNormalizeText(container, result);
3261
3409
  const tomatch = this._resolveUtterancesToMatch(container, scriptingMemory, expected, botMsg);
3262
- this.scriptingEvents.assertBotResponse(response, tomatch, `${this.header.name}/${convoStep.stepTag}`);
3410
+ this.scriptingEvents.assertBotResponse(response, tomatch, `${this.header.name}/${convoStep.stepTag}`, null, convoStepParameters);
3263
3411
  }
3264
3412
  }
3265
3413
  GetScriptingMemoryAllVariables(container) {
@@ -3319,7 +3467,7 @@ class Convo$6 {
3319
3467
  }, []);
3320
3468
  }
3321
3469
  _checkBotRepliesConsumed(container) {
3322
- if (container.caps.SCRIPTING_FORCE_BOT_CONSUMED) {
3470
+ if (container.caps[Capabilities.SCRIPTING_FORCE_BOT_CONSUMED]) {
3323
3471
  const queueLength = container._QueueLength();
3324
3472
  if (queueLength === 1) {
3325
3473
  throw new Error('There is an unread bot reply in queue');
@@ -3391,7 +3539,7 @@ class Convo$6 {
3391
3539
  throw new BotiumError$2(`Cant find partial convo with name ${includeLogicHook} (available partial convos: ${Object.keys(partialConvos).join(',')})`);
3392
3540
  }
3393
3541
  _getEffectiveConversationRecursive(partialConvo.conversation, [...parentPConvos, includeLogicHook], result, true);
3394
- debug$j(`Partial convo ${includeLogicHook} included`);
3542
+ debug$k(`Partial convo ${includeLogicHook} included`);
3395
3543
  });
3396
3544
  });
3397
3545
  return result;
@@ -3412,7 +3560,7 @@ var Convo_1 = {
3412
3560
  TranscriptError
3413
3561
  };
3414
3562
 
3415
- const debug$i = debug$n('botium-core-RetryHelper');
3563
+ const debug$j = debug$o('botium-core-RetryHelper');
3416
3564
  var RetryHelper_1 = class RetryHelper {
3417
3565
  constructor(caps, section, options = {}) {
3418
3566
  this.retryErrorPatterns = [];
@@ -3436,7 +3584,7 @@ var RetryHelper_1 = class RetryHelper {
3436
3584
  minTimeout: caps[`RETRY_${section.toUpperCase()}_MINTIMEOUT`] || (lodash.isNil(options.minTimeout) ? 1000 : options.minTimeout)
3437
3585
  };
3438
3586
  if (this.retrySettings.retries > 0) {
3439
- debug$i(`Retry for ${section} is enabled. Settings: ${JSON.stringify(this.retrySettings)} Patterns: ${JSON.stringify(this.retryErrorPatterns.map(r => r.toString()))}`);
3587
+ debug$j(`Retry for ${section} is enabled. Settings: ${JSON.stringify(this.retrySettings)} Patterns: ${JSON.stringify(this.retryErrorPatterns.map(r => r.toString()))}`);
3440
3588
  }
3441
3589
  }
3442
3590
  shouldRetry(err) {
@@ -3450,26 +3598,36 @@ var RetryHelper_1 = class RetryHelper {
3450
3598
  }
3451
3599
  };
3452
3600
 
3601
+ const debug$i = debug$o('botium-core-MatchFunctions');
3453
3602
  const {
3454
3603
  toString,
3455
3604
  quoteRegexpString,
3456
3605
  calculateWer: calculateWer$1
3457
3606
  } = helper;
3458
- const _normalize = botresponse => {
3607
+ const _normalize = (botresponse, args, convoStepParameters) => {
3608
+ if (!convoStepParameters) {
3609
+ debug$i('Convo step parameters might be missing!');
3610
+ }
3459
3611
  if (lodash.isUndefined(botresponse) || lodash.isNil(botresponse)) return '';
3460
3612
  if (lodash.isObject(botresponse) && lodash.has(botresponse, 'messageText')) {
3461
3613
  return toString(botresponse.messageText) || '';
3462
3614
  }
3463
3615
  return toString(botresponse);
3464
3616
  };
3465
- const regexp = ignoreCase => (botresponse, utterance) => {
3617
+ const regexp = ignoreCase => (botresponse, utterance, args, convoStepParameters) => {
3618
+ if (!convoStepParameters) {
3619
+ debug$i('Convo step parameters might be missing!');
3620
+ }
3466
3621
  if (lodash.isUndefined(botresponse)) return false;
3467
3622
  utterance = toString(utterance);
3468
3623
  botresponse = _normalize(botresponse);
3469
3624
  const regexp = ignoreCase ? new RegExp(utterance, 'i') : new RegExp(utterance, '');
3470
3625
  return regexp.test(botresponse);
3471
3626
  };
3472
- const wildcard = ignoreCase => (botresponse, utterance) => {
3627
+ const wildcard = ignoreCase => (botresponse, utterance, args, convoStepParameters) => {
3628
+ if (!convoStepParameters) {
3629
+ debug$i('Convo step parameters might be missing!');
3630
+ }
3473
3631
  if (lodash.isUndefined(botresponse)) {
3474
3632
  if (utterance.trim() === '*') return true;else return false;
3475
3633
  }
@@ -3483,7 +3641,10 @@ const wildcard = ignoreCase => (botresponse, utterance) => {
3483
3641
  const regexp = ignoreCase ? new RegExp(utteranceRe, 'i') : new RegExp(utteranceRe, '');
3484
3642
  return regexp.test(botresponse);
3485
3643
  };
3486
- const wildcardExact = ignoreCase => (botresponse, utterance) => {
3644
+ const wildcardExact = ignoreCase => (botresponse, utterance, args, convoStepParameters) => {
3645
+ if (!convoStepParameters) {
3646
+ debug$i('Convo step parameters might be missing!');
3647
+ }
3487
3648
  if (lodash.isUndefined(botresponse)) {
3488
3649
  if (utterance.trim() === '*') return true;else return false;
3489
3650
  }
@@ -3497,7 +3658,10 @@ const wildcardExact = ignoreCase => (botresponse, utterance) => {
3497
3658
  const regexp = ignoreCase ? new RegExp(utteranceRe, 'i') : new RegExp(utteranceRe, '');
3498
3659
  return regexp.test(botresponse);
3499
3660
  };
3500
- const include = ignoreCase => (botresponse, utterance) => {
3661
+ const include = ignoreCase => (botresponse, utterance, args, convoStepParameters) => {
3662
+ if (!convoStepParameters) {
3663
+ debug$i('Convo step parameters might be missing!');
3664
+ }
3501
3665
  if (lodash.isUndefined(botresponse)) return false;
3502
3666
  utterance = toString(utterance);
3503
3667
  botresponse = _normalize(botresponse);
@@ -3507,7 +3671,10 @@ const include = ignoreCase => (botresponse, utterance) => {
3507
3671
  }
3508
3672
  return botresponse.indexOf(utterance) >= 0;
3509
3673
  };
3510
- const equals = ignoreCase => (botresponse, utterance) => {
3674
+ const equals = ignoreCase => (botresponse, utterance, args, convoStepParameters) => {
3675
+ if (!convoStepParameters) {
3676
+ debug$i('Convo step parameters might be missing!');
3677
+ }
3511
3678
  if (lodash.isUndefined(botresponse)) return false;
3512
3679
  utterance = toString(utterance);
3513
3680
  botresponse = _normalize(botresponse);
@@ -3517,10 +3684,13 @@ const equals = ignoreCase => (botresponse, utterance) => {
3517
3684
  }
3518
3685
  return botresponse === utterance;
3519
3686
  };
3520
- const wer = () => (botresponse, utterance, args) => {
3687
+ const wer = () => (botresponse, utterance, args, convoStepParameters) => {
3688
+ if (!convoStepParameters) {
3689
+ debug$i('Convo step parameters might be missing!');
3690
+ }
3521
3691
  botresponse = _normalize(botresponse || '');
3522
3692
  utterance = toString(utterance || '');
3523
- const threshold = [',', '.'].find(p => `${args[0]}`.includes(p)) ? parseFloat(args[0]) : parseInt(args[0]) / 100;
3693
+ const threshold = !lodash.isNil(convoStepParameters?.matchingModeWer) ? convoStepParameters?.matchingModeWer / 100 : [',', '.'].find(p => `${args[0]}`.includes(p)) ? parseFloat(args[0]) : parseInt(args[0]) / 100;
3524
3694
  return calculateWer$1(botresponse, utterance) <= threshold;
3525
3695
  };
3526
3696
  const getMatchFunction$1 = matchingMode => {
@@ -3723,7 +3893,7 @@ var JsonToJson = {
3723
3893
  precompile: precompile$2
3724
3894
  };
3725
3895
 
3726
- const debug$h = debug$n('botium-core-HookUtils');
3896
+ const debug$h = debug$o('botium-core-HookUtils');
3727
3897
  const executeHook$2 = async (caps, hook, ...args) => {
3728
3898
  return executeHookSync$1(caps, hook, ...args);
3729
3899
  };
@@ -3823,7 +3993,7 @@ var Script = {
3823
3993
  precompile: precompile$1
3824
3994
  };
3825
3995
 
3826
- const debug$g = debug$n('botium-core-PrecompilerMarkdownRasa');
3996
+ const debug$g = debug$o('botium-core-PrecompilerMarkdownRasa');
3827
3997
  const htmlCommentRegexp = /(<!--.*?-->)/g;
3828
3998
  var precompile = (caps, scriptBuffer, options, filename) => {
3829
3999
  if (!filename.endsWith('.md')) {
@@ -3924,7 +4094,7 @@ var MarkdownRasa = {
3924
4094
  precompile: precompile
3925
4095
  };
3926
4096
 
3927
- const debug$f = debug$n('botium-core-CapabilitiesUtils');
4097
+ const debug$f = debug$o('botium-core-CapabilitiesUtils');
3928
4098
  const {
3929
4099
  toJsonWeak
3930
4100
  } = Utils;
@@ -4015,7 +4185,7 @@ var CapabilitiesUtils = {
4015
4185
  flatCababilities: flatCababilities$1
4016
4186
  };
4017
4187
 
4018
- const debug$e = debug$n('botium-core-Precompilers');
4188
+ const debug$e = debug$o('botium-core-Precompilers');
4019
4189
  const {
4020
4190
  isJsonObject
4021
4191
  } = Utils;
@@ -4142,7 +4312,7 @@ var Utterance_1 = class Utterance {
4142
4312
  }
4143
4313
  };
4144
4314
 
4145
- const debug$d = debug$n('botium-core-CompilerXlsx');
4315
+ const debug$d = debug$o('botium-core-CompilerXlsx');
4146
4316
  const {
4147
4317
  E_SCRIPTING_MEMORY_COLUMN_MODE
4148
4318
  } = Enums;
@@ -4679,7 +4849,7 @@ var CompilerTxt_1 = class CompilerTxt extends CompilerBase_1 {
4679
4849
  Compile(scriptBuffer, scriptType = Constants.SCRIPTING_TYPE_CONVO) {
4680
4850
  let scriptData = scriptBuffer;
4681
4851
  if (Buffer.isBuffer(scriptBuffer)) scriptData = scriptData.toString();
4682
- const lines = lodash.map(scriptData.split(this.eol), line => line.trim());
4852
+ const lines = scriptData.split(this.eol);
4683
4853
  if (scriptType === Constants.SCRIPTING_TYPE_CONVO) {
4684
4854
  return this._compileConvo(lines, false);
4685
4855
  } else if (scriptType === Constants.SCRIPTING_TYPE_PCONVO) {
@@ -4729,7 +4899,6 @@ var CompilerTxt_1 = class CompilerTxt extends CompilerBase_1 {
4729
4899
  };
4730
4900
  lines.forEach(line => {
4731
4901
  currentLineIndex++;
4732
- line = line.trim();
4733
4902
  if (isValidTagLine(line)) {
4734
4903
  pushPrev();
4735
4904
  convoStepSender = line.substr(1).trim();
@@ -4805,7 +4974,7 @@ var CompilerTxt_1 = class CompilerTxt extends CompilerBase_1 {
4805
4974
  const {
4806
4975
  parse
4807
4976
  } = sync;
4808
- const debug$c = debug$n('botium-core-CompilerCsv');
4977
+ const debug$c = debug$o('botium-core-CompilerCsv');
4809
4978
  const {
4810
4979
  Convo: Convo$3
4811
4980
  } = Convo_1;
@@ -5016,7 +5185,7 @@ var CompilerCsv_1 = class CompilerCsv extends CompilerBase_1 {
5016
5185
  }
5017
5186
  };
5018
5187
 
5019
- const debug$b = debug$n('botium-core-CompilerObject');
5188
+ const debug$b = debug$o('botium-core-CompilerObject');
5020
5189
  const {
5021
5190
  Convo: Convo$2
5022
5191
  } = Convo_1;
@@ -5162,7 +5331,7 @@ var CompilerJson_1 = class CompilerJson extends CompilerObjectBase_1 {
5162
5331
  }
5163
5332
  };
5164
5333
 
5165
- const debug$a = debug$n('botium-core-CompilerMarkdown');
5334
+ const debug$a = debug$o('botium-core-CompilerMarkdown');
5166
5335
  const md = new markdownIt();
5167
5336
  const {
5168
5337
  Convo: Convo$1
@@ -5241,7 +5410,7 @@ var CompilerMarkdown_1 = class CompilerMarkdown extends CompilerBase_1 {
5241
5410
  conversation.push(Object.assign({
5242
5411
  sender,
5243
5412
  stepTag: 'Line ' + (step.map[0] + 1)
5244
- }, linesToConvoStep(step.children.map(child => child.content + (child.children ? ' ' + child.children.map(child => child.content).join('|') : '')), sender, this.context, this.eol)));
5413
+ }, linesToConvoStep(step.children.map(child => child.content + (child.children && child.children.length > 0 ? ' ' + child.children.map(child => child.content).join('|') : '')), sender, this.context, this.eol)));
5245
5414
  } else {
5246
5415
  debug$a(`Expected sender ${validSenders.map(s => `'${s}'`).join(' or ')} but found ${sender}`);
5247
5416
  }
@@ -5273,7 +5442,7 @@ var CompilerMarkdown_1 = class CompilerMarkdown extends CompilerBase_1 {
5273
5442
  };
5274
5443
 
5275
5444
  promise.shim();
5276
- const debug$9 = debug$n('botium-core-ScriptingProvider');
5445
+ const debug$9 = debug$o('botium-core-ScriptingProvider');
5277
5446
  const {
5278
5447
  Convo,
5279
5448
  ConvoStep
@@ -5363,7 +5532,7 @@ var ScriptingProvider_1 = class ScriptingProvider {
5363
5532
  }) => {
5364
5533
  return this._createLogicHookPromises({
5365
5534
  hookType: 'onConvoBegin',
5366
- logicHooks: convo.beginLogicHook || [],
5535
+ logicHooks: convo?.beginLogicHook || [],
5367
5536
  convo,
5368
5537
  convoStep,
5369
5538
  scriptingMemory,
@@ -5378,7 +5547,7 @@ var ScriptingProvider_1 = class ScriptingProvider {
5378
5547
  }) => {
5379
5548
  return this._createLogicHookPromises({
5380
5549
  hookType: 'onConvoEnd',
5381
- logicHooks: convo.endLogicHook || [],
5550
+ logicHooks: convo?.endLogicHook || [],
5382
5551
  convo,
5383
5552
  convoStep,
5384
5553
  scriptingMemory,
@@ -5393,7 +5562,7 @@ var ScriptingProvider_1 = class ScriptingProvider {
5393
5562
  }) => {
5394
5563
  return this._createLogicHookPromises({
5395
5564
  hookType: 'onMeStart',
5396
- logicHooks: convoStep.logicHooks || [],
5565
+ logicHooks: convoStep?.logicHooks || [],
5397
5566
  convo,
5398
5567
  convoStep,
5399
5568
  scriptingMemory,
@@ -5408,7 +5577,7 @@ var ScriptingProvider_1 = class ScriptingProvider {
5408
5577
  }) => {
5409
5578
  return this._createLogicHookPromises({
5410
5579
  hookType: 'onMePrepare',
5411
- logicHooks: convoStep.logicHooks || [],
5580
+ logicHooks: convoStep?.logicHooks || [],
5412
5581
  convo,
5413
5582
  convoStep,
5414
5583
  scriptingMemory,
@@ -5423,7 +5592,7 @@ var ScriptingProvider_1 = class ScriptingProvider {
5423
5592
  }) => {
5424
5593
  return this._createLogicHookPromises({
5425
5594
  hookType: 'onMeEnd',
5426
- logicHooks: convoStep.logicHooks || [],
5595
+ logicHooks: convoStep?.logicHooks || [],
5427
5596
  convo,
5428
5597
  convoStep,
5429
5598
  scriptingMemory,
@@ -5438,7 +5607,7 @@ var ScriptingProvider_1 = class ScriptingProvider {
5438
5607
  }) => {
5439
5608
  return this._createLogicHookPromises({
5440
5609
  hookType: 'onBotStart',
5441
- logicHooks: convoStep.logicHooks || [],
5610
+ logicHooks: convoStep?.logicHooks || [],
5442
5611
  convo,
5443
5612
  convoStep,
5444
5613
  scriptingMemory,
@@ -5453,7 +5622,7 @@ var ScriptingProvider_1 = class ScriptingProvider {
5453
5622
  }) => {
5454
5623
  return this._createLogicHookPromises({
5455
5624
  hookType: 'onBotPrepare',
5456
- logicHooks: convoStep.logicHooks || [],
5625
+ logicHooks: convoStep?.logicHooks || [],
5457
5626
  convo,
5458
5627
  convoStep,
5459
5628
  scriptingMemory,
@@ -5468,7 +5637,7 @@ var ScriptingProvider_1 = class ScriptingProvider {
5468
5637
  }) => {
5469
5638
  return this._createLogicHookPromises({
5470
5639
  hookType: 'onBotEnd',
5471
- logicHooks: convoStep.logicHooks || [],
5640
+ logicHooks: convoStep?.logicHooks || [],
5472
5641
  convo,
5473
5642
  convoStep,
5474
5643
  scriptingMemory,
@@ -5483,7 +5652,7 @@ var ScriptingProvider_1 = class ScriptingProvider {
5483
5652
  }) => {
5484
5653
  return this._createAsserterPromises({
5485
5654
  asserterType: 'assertConvoBegin',
5486
- asserters: convo.beginAsserter || [],
5655
+ asserters: convo?.beginAsserter || [],
5487
5656
  convo,
5488
5657
  convoStep,
5489
5658
  scriptingMemory,
@@ -5498,7 +5667,7 @@ var ScriptingProvider_1 = class ScriptingProvider {
5498
5667
  }) => {
5499
5668
  return this._createAsserterPromises({
5500
5669
  asserterType: 'assertConvoStep',
5501
- asserters: convoStep.asserters || [],
5670
+ asserters: convoStep?.asserters || [],
5502
5671
  convo,
5503
5672
  convoStep,
5504
5673
  scriptingMemory,
@@ -5513,7 +5682,7 @@ var ScriptingProvider_1 = class ScriptingProvider {
5513
5682
  }) => {
5514
5683
  return this._createAsserterPromises({
5515
5684
  asserterType: 'assertConvoEnd',
5516
- asserters: convo.endAsserter || [],
5685
+ asserters: convo?.endAsserter || [],
5517
5686
  convo,
5518
5687
  convoStep,
5519
5688
  scriptingMemory,
@@ -5542,24 +5711,26 @@ var ScriptingProvider_1 = class ScriptingProvider {
5542
5711
  resolveEmptyIfUnknown
5543
5712
  });
5544
5713
  },
5545
- assertBotResponse: (botresponse, tomatch, stepTag, meMsg) => {
5714
+ assertBotResponse: (botresponse, tomatch, stepTag, meMsg, convoStepParameters = {}) => {
5546
5715
  if (!lodash.isArray(tomatch)) {
5547
5716
  tomatch = [tomatch];
5548
5717
  }
5549
5718
  debug$9(`assertBotResponse ${stepTag} ${meMsg ? `(${meMsg}) ` : ''}BOT: ${botresponse} = ${tomatch} ...`);
5550
- const found = lodash.find(tomatch, utt => this.matchFn(botresponse, utt, this.caps[Capabilities.SCRIPTING_MATCHING_MODE_ARGS]));
5719
+ const matchFn = convoStepParameters.matchingMode ? getMatchFunction(convoStepParameters.matchingMode) || this.matchFn : this.matchFn;
5720
+ const found = lodash.find(tomatch, utt => matchFn(botresponse, utt, this.caps[Capabilities.SCRIPTING_MATCHING_MODE_ARGS], convoStepParameters));
5551
5721
  const asserterType = this.caps[Capabilities.SCRIPTING_MATCHING_MODE] === 'wer' ? 'Word Error Rate Asserter' : 'Text Match Asserter';
5552
5722
  if (lodash.isNil(found)) {
5553
- if (this.caps[Capabilities.SCRIPTING_MATCHING_MODE] === 'wer') {
5723
+ const matchingMode = convoStepParameters.matchingMode || this.caps[Capabilities.SCRIPTING_MATCHING_MODE];
5724
+ if (matchingMode === 'wer') {
5554
5725
  const wer = calculateWer(botresponse, tomatch[0]);
5555
5726
  const werArgs = this.caps[Capabilities.SCRIPTING_MATCHING_MODE_ARGS];
5556
- const threshold = [',', '.'].find(p => `${werArgs[0]}`.includes(p)) ? parseFloat(werArgs[0]) : parseInt(werArgs[0]) / 100;
5727
+ const threshold = !lodash.isNil(convoStepParameters.matchingModeWer) ? convoStepParameters.matchingModeWer / 100 : [',', '.'].find(p => `${werArgs[0]}`.includes(p)) ? parseFloat(werArgs[0]) : parseInt(werArgs[0]) / 100;
5557
5728
  const message = `${stepTag}: Word Error Rate (${toPercent(wer)}) higher than accepted (${toPercent(threshold)})`;
5558
5729
  throw new BotiumError$1(message, {
5559
5730
  type: 'asserter',
5560
5731
  source: asserterType,
5561
5732
  params: {
5562
- matchingMode: this.caps[Capabilities.SCRIPTING_MATCHING_MODE],
5733
+ matchingMode,
5563
5734
  args: this.caps[Capabilities.SCRIPTING_MATCHING_MODE_ARGS] || null
5564
5735
  },
5565
5736
  context: {
@@ -5597,24 +5768,26 @@ var ScriptingProvider_1 = class ScriptingProvider {
5597
5768
  }
5598
5769
  }
5599
5770
  },
5600
- assertBotNotResponse: (botresponse, nottomatch, stepTag, meMsg) => {
5771
+ assertBotNotResponse: (botresponse, nottomatch, stepTag, meMsg, convoStepParameters = {}) => {
5601
5772
  if (!lodash.isArray(nottomatch)) {
5602
5773
  nottomatch = [nottomatch];
5603
5774
  }
5604
5775
  debug$9(`assertBotNotResponse ${stepTag} ${meMsg ? `(${meMsg}) ` : ''}BOT: ${botresponse} != ${nottomatch} ...`);
5605
- const found = lodash.find(nottomatch, utt => this.matchFn(botresponse, utt, this.caps[Capabilities.SCRIPTING_MATCHING_MODE_ARGS]));
5776
+ const matchFn = convoStepParameters.matchingMode ? getMatchFunction(convoStepParameters.matchingMode) || this.matchFn : this.matchFn;
5777
+ const found = lodash.find(nottomatch, utt => matchFn(botresponse, utt, this.caps[Capabilities.SCRIPTING_MATCHING_MODE_ARGS], convoStepParameters));
5606
5778
  const asserterType = this.caps[Capabilities.SCRIPTING_MATCHING_MODE] === 'wer' ? 'Word Error Rate Asserter' : 'Text Match Asserter';
5607
5779
  if (!lodash.isNil(found)) {
5608
- if (this.caps[Capabilities.SCRIPTING_MATCHING_MODE] === 'wer') {
5780
+ const matchingMode = convoStepParameters.matchingMode || this.caps[Capabilities.SCRIPTING_MATCHING_MODE];
5781
+ if (matchingMode === 'wer') {
5609
5782
  const wer = calculateWer(botresponse, nottomatch[0]);
5610
5783
  const werArgs = this.caps[Capabilities.SCRIPTING_MATCHING_MODE_ARGS];
5611
- const threshold = [',', '.'].find(p => `${werArgs[0]}`.includes(p)) ? parseFloat(werArgs[0]) : parseInt(werArgs[0]) / 100;
5784
+ const threshold = !lodash.isNil(convoStepParameters.matchingModeWer) ? convoStepParameters.matchingModeWer / 100 : [',', '.'].find(p => `${werArgs[0]}`.includes(p)) ? parseFloat(werArgs[0]) : parseInt(werArgs[0]) / 100;
5612
5785
  const message = `${stepTag}: Word Error Rate (${toPercent(wer)}) lower than accepted (${toPercent(threshold)})`;
5613
5786
  throw new BotiumError$1(message, {
5614
5787
  type: 'asserter',
5615
5788
  source: asserterType,
5616
5789
  params: {
5617
- matchingMode: this.caps[Capabilities.SCRIPTING_MATCHING_MODE],
5790
+ matchingMode,
5618
5791
  args: this.caps[Capabilities.SCRIPTING_MATCHING_MODE_ARGS] || null
5619
5792
  },
5620
5793
  context: {
@@ -5676,6 +5849,22 @@ var ScriptingProvider_1 = class ScriptingProvider {
5676
5849
  assertConvoStep: 'assertNotConvoStep',
5677
5850
  assertConvoEnd: 'assertNotConvoEnd'
5678
5851
  };
5852
+ const updateExceptionContext = (promise, asserter) => {
5853
+ const updateError = err => {
5854
+ if (err instanceof BotiumError$1) {
5855
+ if (!err.context) {
5856
+ err.context = {};
5857
+ }
5858
+ err.context.asserter = asserter.name;
5859
+ throw err;
5860
+ } else {
5861
+ throw botiumErrorFromErr(lodash.isString(err) ? err : err.message, err, {
5862
+ asserter: asserter.name
5863
+ });
5864
+ }
5865
+ };
5866
+ return promise.catch(err => updateError(err));
5867
+ };
5679
5868
  const callAsserter = (asserterSpec, asserter, params) => {
5680
5869
  if (asserterSpec.not) {
5681
5870
  const notAsserterType = mapNot[asserterType];
@@ -5699,24 +5888,36 @@ var ScriptingProvider_1 = class ScriptingProvider {
5699
5888
  return p(this.retryHelperAsserter, () => asserter[asserterType](params));
5700
5889
  }
5701
5890
  };
5702
- const convoAsserter = asserters.filter(a => this.asserters[a.name][asserterType]).map(a => callAsserter(a, this.asserters[a.name], {
5703
- convo,
5704
- convoStep,
5705
- scriptingMemory,
5706
- container,
5707
- args: ScriptingMemory.applyToArgs(a.args, scriptingMemory, container.caps, rest.botMsg),
5708
- isGlobal: false,
5709
- ...rest
5710
- }));
5711
- const globalAsserter = Object.values(this.globalAsserter).filter(a => a[asserterType]).map(a => p(this.retryHelperAsserter, () => a[asserterType]({
5712
- convo,
5713
- convoStep,
5714
- scriptingMemory,
5715
- container,
5716
- args: [],
5717
- isGlobal: true,
5718
- ...rest
5719
- })));
5891
+ const convoAsserter = asserters.filter(a => this.asserters[a.name][asserterType]).map(a => ({
5892
+ asserter: a,
5893
+ promise: callAsserter(a, this.asserters[a.name], {
5894
+ convo,
5895
+ convoStep,
5896
+ scriptingMemory,
5897
+ container,
5898
+ args: ScriptingMemory.applyToArgs(a.args, scriptingMemory, container.caps, rest.botMsg),
5899
+ isGlobal: false,
5900
+ ...rest
5901
+ })
5902
+ })).map(({
5903
+ promise,
5904
+ asserter
5905
+ }) => updateExceptionContext(promise, asserter));
5906
+ const globalAsserter = Object.values(this.globalAsserter).filter(a => a[asserterType]).map(a => ({
5907
+ asserter: a,
5908
+ promise: p(this.retryHelperAsserter, () => a[asserterType]({
5909
+ convo,
5910
+ convoStep,
5911
+ scriptingMemory,
5912
+ container,
5913
+ args: [],
5914
+ isGlobal: true,
5915
+ ...rest
5916
+ }))
5917
+ })).map(({
5918
+ promise,
5919
+ asserter
5920
+ }) => updateExceptionContext(promise, asserter));
5720
5921
  const allPromises = [...convoAsserter, ...globalAsserter];
5721
5922
  if (this.caps[Capabilities.SCRIPTING_ENABLE_MULTIPLE_ASSERT_ERRORS]) {
5722
5923
  return Promise.allSettled(allPromises).then(results => {
@@ -5742,7 +5943,8 @@ var ScriptingProvider_1 = class ScriptingProvider {
5742
5943
  if (hookType !== 'onMeStart' && hookType !== 'onMePrepare' && hookType !== 'onMeEnd' && hookType !== 'onBotStart' && hookType !== 'onBotPrepare' && hookType !== 'onBotEnd' && hookType !== 'onConvoBegin' && hookType !== 'onConvoEnd') {
5743
5944
  throw Error(`Unknown hookType ${hookType}`);
5744
5945
  }
5745
- const convoStepPromises = (logicHooks || []).filter(l => this.logicHooks[l.name][hookType]).map(l => p(this.retryHelperLogicHook, () => this.logicHooks[l.name][hookType]({
5946
+ const localHooks = (logicHooks || []).filter(l => this.logicHooks[l.name][hookType]);
5947
+ const convoStepPromises = localHooks.map(l => p(this.retryHelperLogicHook, () => this.logicHooks[l.name][hookType]({
5746
5948
  convo,
5747
5949
  convoStep,
5748
5950
  scriptingMemory,
@@ -5751,7 +5953,8 @@ var ScriptingProvider_1 = class ScriptingProvider {
5751
5953
  isGlobal: false,
5752
5954
  ...rest
5753
5955
  })));
5754
- const globalPromises = Object.values(this.globalLogicHook).filter(l => l[hookType]).map(l => p(this.retryHelperLogicHook, () => l[hookType]({
5956
+ const globalHooks = Object.values(this.globalLogicHook).filter(l => l[hookType]);
5957
+ const globalPromises = globalHooks.map(l => p(this.retryHelperLogicHook, () => l[hookType]({
5755
5958
  convo,
5756
5959
  convoStep,
5757
5960
  scriptingMemory,
@@ -5761,7 +5964,14 @@ var ScriptingProvider_1 = class ScriptingProvider {
5761
5964
  ...rest
5762
5965
  })));
5763
5966
  const allPromises = [...convoStepPromises, ...globalPromises];
5764
- if (allPromises.length > 0) return Promise.all(allPromises).then(() => true);
5967
+ if (allPromises.length > 0) {
5968
+ return Promise.all(allPromises).then(() => {
5969
+ return {
5970
+ // just returning some humanreadable
5971
+ hooks: [...localHooks, ...globalHooks].map(h => h.name || h.context?.ref || JSON.stringify(h))
5972
+ };
5973
+ });
5974
+ }
5765
5975
  return Promise.resolve(false);
5766
5976
  }
5767
5977
  _createUserInputPromises({
@@ -5771,7 +5981,7 @@ var ScriptingProvider_1 = class ScriptingProvider {
5771
5981
  container,
5772
5982
  ...rest
5773
5983
  }) {
5774
- const convoStepPromises = (convoStep.userInputs || []).filter(ui => this.userInputs[ui.name]).map(ui => p(this.retryHelperUserInput, () => this.userInputs[ui.name].setUserInput({
5984
+ const convoStepPromises = (convoStep?.userInputs || []).filter(ui => this.userInputs[ui.name]).map(ui => p(this.retryHelperUserInput, () => this.userInputs[ui.name].setUserInput({
5775
5985
  convo,
5776
5986
  convoStep,
5777
5987
  scriptingMemory,
@@ -5833,6 +6043,11 @@ var ScriptingProvider_1 = class ScriptingProvider {
5833
6043
  }
5834
6044
  };
5835
6045
  }
6046
+
6047
+ // Livechat, and crawler using logichooks too. So they need script context
6048
+ BuildScriptContext() {
6049
+ return this._buildScriptContext();
6050
+ }
5836
6051
  Build() {
5837
6052
  const CompilerXlsx = CompilerXlsx_1;
5838
6053
  this.compilers[Constants.SCRIPTING_FORMAT_XSLX] = new CompilerXlsx(this._buildScriptContext(), this.caps);
@@ -6938,7 +7153,7 @@ var NoRepo_1 = class NoRepo extends BaseRepo_1 {
6938
7153
  };
6939
7154
 
6940
7155
  var ProcessUtils = createCommonjsModule(function (module) {
6941
- const debug = debug$n('botium-core-ProcessUtils');
7156
+ const debug = debug$o('botium-core-ProcessUtils');
6942
7157
  module.exports = {
6943
7158
  childCommandLineRun: (cmd, ignoreErrors = false, processOptions = {}) => {
6944
7159
  const cmdOptions = cmd.split(' ');
@@ -6989,7 +7204,7 @@ var ProcessUtils = createCommonjsModule(function (module) {
6989
7204
  ProcessUtils.childCommandLineRun;
6990
7205
  ProcessUtils.childProcessRun;
6991
7206
 
6992
- const debug$8 = debug$n('botium-core-GitRepo');
7207
+ const debug$8 = debug$o('botium-core-GitRepo');
6993
7208
  var GitRepo_1 = class GitRepo extends BaseRepo_1 {
6994
7209
  Validate() {
6995
7210
  return super.Validate().then(() => {
@@ -7138,7 +7353,7 @@ var Queue_1 = class Queue {
7138
7353
  }
7139
7354
  };
7140
7355
 
7141
- const debug$7 = debug$n('botium-connector-BaseContainer');
7356
+ const debug$7 = debug$o('botium-connector-BaseContainer');
7142
7357
  const {
7143
7358
  executeHook: executeHook$1,
7144
7359
  getHook: getHook$1
@@ -7339,7 +7554,7 @@ var BaseContainer_1 = class BaseContainer {
7339
7554
  }
7340
7555
  };
7341
7556
 
7342
- const debug$6 = debug$n('botium-connector-GridContainer');
7557
+ const debug$6 = debug$o('botium-connector-GridContainer');
7343
7558
  var GridContainer_1 = class GridContainer extends BaseContainer_1 {
7344
7559
  Validate() {
7345
7560
  return super.Validate().then(() => {
@@ -7539,7 +7754,7 @@ var InProcessContainer_1 = class InProcessContainer extends BaseContainer_1 {
7539
7754
  }
7540
7755
  };
7541
7756
 
7542
- const debug$5 = debug$n('botium-core-inbound-proxy');
7757
+ const debug$5 = debug$o('botium-core-inbound-proxy');
7543
7758
  const buildRedisHandler = (redisurl, topic) => {
7544
7759
  const redis = new ioredis(redisurl);
7545
7760
  redis.on('connect', () => {
@@ -7617,7 +7832,7 @@ proxy.startProxy;
7617
7832
  const {
7618
7833
  v4: uuidv4
7619
7834
  } = uuid;
7620
- const debug$4 = debug$n('botium-connector-simplerest');
7835
+ const debug$4 = debug$o('botium-connector-simplerest');
7621
7836
  const {
7622
7837
  startProxy
7623
7838
  } = proxy;
@@ -8571,7 +8786,7 @@ var SimpleRestContainer_1 = class SimpleRestContainer {
8571
8786
  }
8572
8787
  };
8573
8788
 
8574
- const debug$3 = debug$n('botium-connector-PluginConnectorContainer-helper');
8789
+ const debug$3 = debug$o('botium-connector-PluginConnectorContainer-helper');
8575
8790
  const pluginResolver = containermode => {
8576
8791
  if (containermode === 'simplerest') {
8577
8792
  return SimpleRestContainer_1;
@@ -8699,7 +8914,7 @@ var plugins = {
8699
8914
  tryLoadPlugin: tryLoadPlugin$1
8700
8915
  };
8701
8916
 
8702
- const debug$2 = debug$n('botium-connector-PluginConnectorContainer');
8917
+ const debug$2 = debug$o('botium-connector-PluginConnectorContainer');
8703
8918
  const {
8704
8919
  tryLoadPlugin
8705
8920
  } = plugins;
@@ -8854,7 +9069,7 @@ const {
8854
9069
  const {
8855
9070
  boolean
8856
9071
  } = boolean$1;
8857
- const debug$1 = debug$n('botium-core-BotDriver');
9072
+ const debug$1 = debug$o('botium-core-BotDriver');
8858
9073
  const {
8859
9074
  version
8860
9075
  } = require$$3;
@@ -9157,7 +9372,7 @@ var BotDriver_1 = class BotDriver {
9157
9372
  }
9158
9373
  };
9159
9374
 
9160
- const debug = debug$n('botium-core-Plugins');
9375
+ const debug = debug$o('botium-core-Plugins');
9161
9376
  const PLUGIN_TYPE_CONNECTOR = 'PLUGIN_TYPE_CONNECTOR';
9162
9377
  const PLUGIN_TYPE_ASSERTER = 'PLUGIN_TYPE_ASSERTER';
9163
9378
  const PLUGIN_TYPE_LOGICHOOK = 'PLUGIN_TYPE_LOGICHOOK';