botium-core 1.14.0 → 1.14.3

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 (38) hide show
  1. package/dist/botium-cjs.js +302 -94
  2. package/dist/botium-cjs.js.map +1 -1
  3. package/dist/botium-es.js +302 -94
  4. package/dist/botium-es.js.map +1 -1
  5. package/package.json +19 -19
  6. package/src/Capabilities.js +2 -0
  7. package/src/scripting/BotiumError.js +40 -3
  8. package/src/scripting/Convo.js +139 -28
  9. package/src/scripting/ScriptingMemory.js +7 -0
  10. package/src/scripting/ScriptingProvider.js +79 -30
  11. package/src/scripting/logichook/LogicHookConsts.js +5 -2
  12. package/src/scripting/logichook/LogicHookUtils.js +8 -6
  13. package/src/scripting/logichook/logichooks/ConditionalBusinessHoursLogicHook.js +1 -1
  14. package/src/scripting/logichook/logichooks/ConditionalCapabilityValueBasedLogicHook.js +1 -1
  15. package/src/scripting/logichook/logichooks/ConditionalJsonPathBasedLogicHook.js +1 -1
  16. package/src/scripting/logichook/logichooks/ConditionalTimeBasedLogicHook.js +1 -1
  17. package/src/scripting/logichook/logichooks/ConvoStepParametersLogicHook.js +6 -0
  18. package/src/scripting/logichook/logichooks/OrderedListToButtonLogicHook.js +37 -0
  19. package/test/convo/fillAndApplyScriptingMemory.spec.js +11 -0
  20. package/test/logichooks/orderedListToButton.spec.js +35 -0
  21. package/test/scripting/asserters/convoStepParameters.spec.js +140 -0
  22. package/test/scripting/asserters/convos/TEXT_GOOD.convo.txt +6 -0
  23. package/test/scripting/asserters/convos/convo_step_parameter_matchmode_failed.convo.txt +8 -0
  24. package/test/scripting/asserters/convos/convo_step_parameter_retry_asserters_all_good.convo.txt +9 -0
  25. package/test/scripting/asserters/convos/convo_step_parameter_retry_asserters_botium_timeout.convo.txt +9 -0
  26. package/test/scripting/asserters/convos/convo_step_parameter_retry_asserters_good.convo.txt +9 -0
  27. package/test/scripting/asserters/convos/convo_step_parameter_retry_asserters_good_global.convo.txt +9 -0
  28. package/test/scripting/asserters/convos/convo_step_parameter_retry_main_and_asserter.convo.txt +10 -0
  29. package/test/scripting/asserters/convos/convo_step_parameter_retry_main_botium_timeout.convo.txt +9 -0
  30. package/test/scripting/asserters/convos/convo_step_parameter_retry_main_but_no_button.convo.txt +10 -0
  31. package/test/scripting/asserters/convos/convo_step_parameter_retry_main_good.convo.txt +9 -0
  32. package/test/scripting/asserters/convos/convo_step_parameter_retry_main_good_begin.convo.txt +11 -0
  33. package/test/scripting/logichooks/convos/conditional_steps_multiple_condition_groups_no_assertion.convo.txt +6 -6
  34. package/test/scripting/logichooks/convos/conditional_steps_multiple_mandatory_condition_groups.convo.txt +20 -0
  35. package/test/scripting/logichooks/convos/conditional_steps_multiple_optional_condition_groups.convo.txt +20 -0
  36. package/test/scripting/logichooks/customConditionalStepLogicHook.spec.js +16 -0
  37. package/test/scripting/matching/matchingmode.spec.js +4 -1
  38. package/test/scripting/scriptingProvider.spec.js +38 -12
@@ -77,7 +77,7 @@ var express__default = /*#__PURE__*/_interopDefaultLegacy(express);
77
77
  var bodyParser__default = /*#__PURE__*/_interopDefaultLegacy(bodyParser);
78
78
 
79
79
  var name = "botium-core";
80
- var version$1 = "1.14.0";
80
+ var version$1 = "1.14.3";
81
81
  var description = "The Selenium for Chatbots";
82
82
  var main = "index.js";
83
83
  var module$1 = "dist/botium-es.js";
@@ -108,12 +108,12 @@ var bugs = {
108
108
  };
109
109
  var homepage = "https://www.botium.ai";
110
110
  var dependencies = {
111
- "@babel/runtime": "^7.22.15",
112
- async: "^3.2.4",
111
+ "@babel/runtime": "^7.23.5",
112
+ async: "^3.2.5",
113
113
  "body-parser": "^1.20.2",
114
114
  boolean: "^3.2.0",
115
115
  bottleneck: "^2.19.5",
116
- "csv-parse": "^5.5.0",
116
+ "csv-parse": "^5.5.3",
117
117
  debug: "^4.3.4",
118
118
  express: "^4.18.2",
119
119
  globby: "11.0.4",
@@ -122,7 +122,7 @@ var dependencies = {
122
122
  "is-json": "^2.0.1",
123
123
  jsonpath: "^1.1.1",
124
124
  lodash: "^4.17.21",
125
- "markdown-it": "^13.0.1",
125
+ "markdown-it": "^14.0.0",
126
126
  "mime-types": "^2.1.35",
127
127
  mkdirp: "^3.0.1",
128
128
  moment: "^2.29.4",
@@ -132,7 +132,7 @@ var dependencies = {
132
132
  "promise.allsettled": "^1.0.7",
133
133
  randomatic: "^3.1.1",
134
134
  request: "^2.88.2",
135
- rimraf: "^5.0.1",
135
+ rimraf: "^5.0.5",
136
136
  "sanitize-filename": "^1.6.3",
137
137
  slugify: "^1.6.6",
138
138
  "socket.io": "^4.7.2",
@@ -140,31 +140,31 @@ var dependencies = {
140
140
  "socketio-auth": "^0.1.1",
141
141
  "swagger-jsdoc": "^6.2.8",
142
142
  "swagger-ui-express": "^5.0.0",
143
- uuid: "^9.0.0",
143
+ uuid: "^9.0.1",
144
144
  "word-error-rate": "0.0.7",
145
145
  "write-yaml": "^1.0.0",
146
146
  xlsx: "^0.18.5",
147
147
  xregexp: "^5.1.1",
148
- yaml: "^2.3.2"
148
+ yaml: "^2.3.4"
149
149
  };
150
150
  var devDependencies = {
151
- "@babel/core": "^7.22.17",
152
- "@babel/node": "^7.22.15",
153
- "@babel/plugin-transform-runtime": "^7.22.15",
154
- "@babel/preset-env": "^7.22.15",
155
- chai: "^4.3.8",
151
+ "@babel/core": "^7.23.5",
152
+ "@babel/node": "^7.22.19",
153
+ "@babel/plugin-transform-runtime": "^7.23.4",
154
+ "@babel/preset-env": "^7.23.5",
155
+ chai: "^4.3.10",
156
156
  "chai-as-promised": "^7.1.1",
157
157
  "cross-env": "^7.0.3",
158
- eslint: "^8.49.0",
158
+ eslint: "^8.55.0",
159
159
  "eslint-config-standard": "^17.1.0",
160
- "eslint-plugin-import": "^2.28.1",
161
- "eslint-plugin-mocha": "^10.1.0",
162
- "eslint-plugin-n": "^16.1.0",
160
+ "eslint-plugin-import": "^2.29.0",
161
+ "eslint-plugin-mocha": "^10.2.0",
162
+ "eslint-plugin-n": "^16.4.0",
163
163
  "eslint-plugin-promise": "^6.1.1",
164
164
  "eslint-plugin-standard": "^4.1.0",
165
165
  mocha: "^10.2.0",
166
- nock: "^13.3.3",
167
- "npm-check-updates": "^16.13.3",
166
+ nock: "^13.4.0",
167
+ "npm-check-updates": "^16.14.11",
168
168
  nyc: "^15.1.0",
169
169
  rollup: "2.79.1",
170
170
  "rollup-plugin-babel": "^4.4.0",
@@ -367,6 +367,8 @@ var Capabilities = {
367
367
  // varnames, testcasenames
368
368
  SCRIPTING_MEMORY_COLUMN_MODE: 'SCRIPTING_MEMORY_COLUMN_MODE',
369
369
  // Botium Lifecycle Hooks
370
+ SCRIPTING_CONVO_STEP_PARAMETERS: 'SCRIPTING_CONVO_STEP_PARAMETERS',
371
+ // Botium Lifecycle Hooks
370
372
  CUSTOMHOOK_ONBUILD: 'CUSTOMHOOK_ONBUILD',
371
373
  CUSTOMHOOK_ONSTART: 'CUSTOMHOOK_ONSTART',
372
374
  CUSTOMHOOK_ONUSERSAYS: 'CUSTOMHOOK_ONUSERSAYS',
@@ -528,6 +530,7 @@ Capabilities.SCRIPTING_UTTEXPANSION_NAMING_UTTERANCE_MAX;
528
530
  Capabilities.SCRIPTING_MEMORYEXPANSION_KEEP_ORIG;
529
531
  Capabilities.SCRIPTING_MEMORY_MATCHING_MODE;
530
532
  Capabilities.SCRIPTING_MEMORY_COLUMN_MODE;
533
+ Capabilities.SCRIPTING_CONVO_STEP_PARAMETERS;
531
534
  Capabilities.CUSTOMHOOK_ONBUILD;
532
535
  Capabilities.CUSTOMHOOK_ONSTART;
533
536
  Capabilities.CUSTOMHOOK_ONUSERSAYS;
@@ -1076,6 +1079,12 @@ var LogicHookConsts = {
1076
1079
  }, {
1077
1080
  name: 'CONDITIONAL_STEP_JSON_PATH_BASED',
1078
1081
  className: 'ConditionalJsonPathBasedLogicHook.js'
1082
+ }, {
1083
+ name: 'CONVO_STEP_PARAMETERS',
1084
+ className: 'ConvoStepParametersLogicHook.js'
1085
+ }, {
1086
+ name: 'ORDERED_LIST_TO_BUTTON',
1087
+ className: 'OrderedListToButtonLogicHook'
1079
1088
  }],
1080
1089
  DEFAULT_USER_INPUTS: [{
1081
1090
  name: 'BUTTON',
@@ -1086,12 +1095,14 @@ var LogicHookConsts = {
1086
1095
  }, {
1087
1096
  name: 'FORM',
1088
1097
  className: 'FormInput'
1089
- }]
1098
+ }],
1099
+ LOGIC_HOOK_EVENTS: ['onConvoBegin', 'onMeStart', 'onMePrepare', 'onMeEnd', 'onBotStart', 'onBotEnd', 'onBotPrepare', 'onConvoEnd']
1090
1100
  };
1091
1101
  LogicHookConsts.LOGIC_HOOK_INCLUDE;
1092
1102
  LogicHookConsts.DEFAULT_ASSERTERS;
1093
1103
  LogicHookConsts.DEFAULT_LOGIC_HOOKS;
1094
1104
  LogicHookConsts.DEFAULT_USER_INPUTS;
1105
+ LogicHookConsts.LOGIC_HOOK_EVENTS;
1095
1106
 
1096
1107
  const debug$m = debug__default["default"]('botium-core-asserterUtils');
1097
1108
  const {
@@ -1242,6 +1253,7 @@ var LogicHookUtils_1 = class LogicHookUtils {
1242
1253
  throw new Error(`Logic Hook specification ${ref} ${hookType} (${packageName}) invalid: ${err.message}`);
1243
1254
  }
1244
1255
  }
1256
+ const typeAsText = hookType === 'asserter' ? 'Asserter' : hookType === 'logichook' ? 'Logic Hook' : hookType === 'userinput' ? 'User Input' : 'Unknown';
1245
1257
  if (isClass__default["default"](src)) {
1246
1258
  try {
1247
1259
  const CheckClass = src;
@@ -1250,7 +1262,7 @@ var LogicHookUtils_1 = class LogicHookUtils {
1250
1262
  ...this.buildScriptContext
1251
1263
  }, this.caps, args);
1252
1264
  } catch (err) {
1253
- throw new Error(`Logic Hook specification ${ref} from class invalid: ${err.message}`);
1265
+ throw new Error(`${typeAsText} specification ${ref} from class invalid: ${err.message}`);
1254
1266
  }
1255
1267
  }
1256
1268
  if (lodash__default["default"].isFunction(src)) {
@@ -1260,7 +1272,7 @@ var LogicHookUtils_1 = class LogicHookUtils {
1260
1272
  ...this.buildScriptContext
1261
1273
  }, this.caps, args);
1262
1274
  } catch (err) {
1263
- throw new Error(`Logic Hook specification ${ref} from function invalid: ${err.message}`);
1275
+ throw new Error(`${typeAsText} specification ${ref} from function invalid: ${err.message}`);
1264
1276
  }
1265
1277
  }
1266
1278
  if (lodash__default["default"].isObject(src) && !lodash__default["default"].isString(src)) {
@@ -1278,7 +1290,7 @@ var LogicHookUtils_1 = class LogicHookUtils {
1278
1290
  }, {});
1279
1291
  return hookObject;
1280
1292
  } catch (err) {
1281
- throw new Error(`Logic Hook specification ${ref} ${hookType} from provided src (${util__default["default"].inspect(src)}) invalid: ${err.message}`);
1293
+ throw new Error(`${typeAsText} specification ${ref} ${hookType} from provided src (${util__default["default"].inspect(src)}) invalid: ${err.message}`);
1282
1294
  }
1283
1295
  }
1284
1296
  if (lodash__default["default"].isString(src)) {
@@ -1339,7 +1351,7 @@ var LogicHookUtils_1 = class LogicHookUtils {
1339
1351
  try {
1340
1352
  return tryLoadFromSource(tryLoadFile, tryLoad.tryLoadAsserterByName);
1341
1353
  } catch (err) {
1342
- loadErr.push(`Logic Hook specification ${ref} ${hookType} from "${src}" invalid: ${err.message} `);
1354
+ loadErr.push(`${typeAsText} specification ${ref} ${hookType} from "${src}" invalid: ${err.message} `);
1343
1355
  }
1344
1356
  }
1345
1357
  }
@@ -1348,13 +1360,13 @@ var LogicHookUtils_1 = class LogicHookUtils {
1348
1360
  try {
1349
1361
  return tryLoadFromSource(tryLoad.tryLoadPackageName, tryLoad.tryLoadAsserterByName);
1350
1362
  } catch (err) {
1351
- loadErr.push(`Logic Hook specification ${ref} ${hookType} from "${src}" invalid: ${err.message} `);
1363
+ loadErr.push(`${typeAsText} specification ${ref} ${hookType} from "${src}" invalid: ${err.message} `);
1352
1364
  }
1353
1365
  }
1354
1366
  }
1355
1367
  loadErr.forEach(debug$m);
1356
1368
  }
1357
- throw new Error(`Logic Hook specification ${ref} ${hookType} from "${util__default["default"].inspect(src)}" invalid : no loader available`);
1369
+ throw new Error(`${typeAsText} specification ${ref} ${hookType} from "${util__default["default"].inspect(src)}" invalid : no loader available`);
1358
1370
  }
1359
1371
  };
1360
1372
 
@@ -2247,6 +2259,44 @@ const BotiumError$4 = class BotiumError extends Error {
2247
2259
  return null;
2248
2260
  }
2249
2261
  }
2262
+ hasError({
2263
+ type,
2264
+ source
2265
+ }) {
2266
+ if (this.context) {
2267
+ const errArr = lodash__default["default"].isArray(this.context) ? this.context : [this.context];
2268
+ for (const err of errArr) {
2269
+ if (err.type === 'list') {
2270
+ for (const internal of err.errors) {
2271
+ if ((!type || internal.type === type) && (!source || internal.source === source)) {
2272
+ return true;
2273
+ }
2274
+ }
2275
+ }
2276
+ if ((!type || err.type === type) && (!source || err.source === source)) {
2277
+ return true;
2278
+ }
2279
+ }
2280
+ } else {
2281
+ return false;
2282
+ }
2283
+ }
2284
+ toArray() {
2285
+ if (this.context) {
2286
+ let result = [];
2287
+ const errArr = lodash__default["default"].isArray(this.context) ? this.context : [this.context];
2288
+ for (const err of errArr) {
2289
+ if (err.type === 'list') {
2290
+ result = result.concat(err.errors);
2291
+ } else {
2292
+ result.push(err);
2293
+ }
2294
+ }
2295
+ return result;
2296
+ } else {
2297
+ return [];
2298
+ }
2299
+ }
2250
2300
  };
2251
2301
  const _getChildErrorsFromContext = context => {
2252
2302
  if (context && context.errors && lodash__default["default"].isArray(context.errors)) {
@@ -2254,12 +2304,16 @@ const _getChildErrorsFromContext = context => {
2254
2304
  }
2255
2305
  return false;
2256
2306
  };
2257
- const botiumErrorFromErr$2 = (message, err) => {
2307
+ const botiumErrorFromErr$2 = (message, err, context = {}) => {
2258
2308
  if (err instanceof BotiumError$4) {
2259
- return new BotiumError$4(message, err.context, true);
2309
+ return new BotiumError$4(message, {
2310
+ ...err.context,
2311
+ ...context
2312
+ }, true);
2260
2313
  } else {
2261
2314
  return new BotiumError$4(message, {
2262
- err
2315
+ err,
2316
+ ...context
2263
2317
  }, true);
2264
2318
  }
2265
2319
  };
@@ -2534,6 +2588,13 @@ const _apply = (scriptingMemory, str, caps, mockMsg) => {
2534
2588
  return arg;
2535
2589
  }
2536
2590
  });
2591
+ args = args.map(arg => {
2592
+ const argStr = `${arg}`;
2593
+ if (argStr.startsWith('$')) {
2594
+ return scriptingMemory[argStr.substring(1)] || arg;
2595
+ }
2596
+ return arg;
2597
+ });
2537
2598
  str = str.replace(match, SCRIPTING_FUNCTIONS$1[key].handler(caps, ...args, mockMsg));
2538
2599
  } else {
2539
2600
  str = str.replace(match, SCRIPTING_FUNCTIONS$1[key].handler(caps));
@@ -2911,8 +2972,54 @@ class Convo$6 {
2911
2972
  let botMsg = null;
2912
2973
  let waitForBotSays = true;
2913
2974
  let skipTranscriptStep = false;
2914
- for (let i = 0; i < this.conversation.length; i++) {
2975
+ let conditionalGroupId = null;
2976
+ let conditionMetInGroup = false;
2977
+ let globalConvoStepParameters = container.caps[Capabilities.SCRIPTING_CONVO_STEP_PARAMETERS] || {};
2978
+ let retryBotMessageTimeoutEnd = null;
2979
+ let retryBotMessageConvoId = null;
2980
+ let retryBotMessageDropBotResponse = false;
2981
+ for (let i = 0; i < this.conversation.length; i = retryBotMessageDropBotResponse ? i : i + 1) {
2982
+ retryBotMessageDropBotResponse = false;
2915
2983
  const convoStep = this.conversation[i];
2984
+ const rawConvoStepParameters = convoStep.logicHooks.find(lh => lh.name === 'CONVO_STEP_PARAMETERS')?.args;
2985
+ let convoStepParameters = {};
2986
+ if (rawConvoStepParameters && rawConvoStepParameters.length) {
2987
+ let params;
2988
+ if (rawConvoStepParameters[0].trim().startsWith('{')) {
2989
+ try {
2990
+ params = JSON.parse(rawConvoStepParameters[0]);
2991
+ } catch (e) {
2992
+ debug$j(`${this.header.name}/${convoStep.stepTag}: Failed to parse convo step parameters from JSON ${rawConvoStepParameters[0]}`);
2993
+ }
2994
+ }
2995
+ if (!params || !Object.keys(params).length) {
2996
+ params = {};
2997
+ for (const param of rawConvoStepParameters) {
2998
+ const semicolon = param.indexOf(':');
2999
+ if (semicolon) {
3000
+ try {
3001
+ const name = param.substring(0, semicolon);
3002
+ const value = param.substring(semicolon + 1);
3003
+ params[name] = value;
3004
+ } catch (e) {
3005
+ debug$j(`${this.header.name}/${convoStep.stepTag}: Failed to parse convo step parameter from arg ${param}`);
3006
+ }
3007
+ }
3008
+ }
3009
+ }
3010
+ if (convoStep.sender === 'begin') {
3011
+ globalConvoStepParameters = Object.assign({}, globalConvoStepParameters || {}, params);
3012
+ } else {
3013
+ convoStepParameters = Object.assign({}, globalConvoStepParameters || {}, params);
3014
+ }
3015
+ } else {
3016
+ if (convoStep.sender !== 'begin') {
3017
+ convoStepParameters = globalConvoStepParameters;
3018
+ }
3019
+ }
3020
+ if (Object.keys(convoStepParameters).length) {
3021
+ debug$j(`${this.header.name}: using convo step parameters ${JSON.stringify(convoStepParameters)}`);
3022
+ }
2916
3023
  const currentStepIndex = i;
2917
3024
  container.eventEmitter.emit(Events.CONVO_STEP_NEXT, container, convoStep, i);
2918
3025
  skipTranscriptStep = false;
@@ -2976,8 +3083,8 @@ class Convo$6 {
2976
3083
  const coreMsg = lodash__default["default"].omit(removeBuffers(meMsg), ['sourceData']);
2977
3084
  debug$j(`${this.header.name}/${convoStep.stepTag}: user says (cleaned by binary and base64 data and sourceData) ${JSON.stringify(coreMsg, null, 2)}`);
2978
3085
  await new Promise(resolve => {
2979
- if (container.caps.SIMULATE_WRITING_SPEED && meMsg.messageText && meMsg.messageText.length) {
2980
- setTimeout(() => resolve(), container.caps.SIMULATE_WRITING_SPEED * meMsg.messageText.length);
3086
+ if (container.caps[Capabilities.SIMULATE_WRITING_SPEED] && meMsg.messageText && meMsg.messageText.length) {
3087
+ setTimeout(() => resolve(), container.caps[Capabilities.SIMULATE_WRITING_SPEED] * meMsg.messageText.length);
2981
3088
  } else {
2982
3089
  resolve();
2983
3090
  }
@@ -3033,7 +3140,6 @@ class Convo$6 {
3033
3140
  throw failErr;
3034
3141
  }
3035
3142
  } else if (convoStep.sender === 'bot') {
3036
- const previousWaitForBotSays = waitForBotSays;
3037
3143
  if (waitForBotSays) {
3038
3144
  botMsg = null;
3039
3145
  } else {
@@ -3090,20 +3196,36 @@ class Convo$6 {
3090
3196
  throw failErr;
3091
3197
  }
3092
3198
  if (convoStep.conditional) {
3093
- const nextConvoStep = this.conversation[i + 1];
3094
- if (!previousWaitForBotSays) {
3095
- skipTranscriptStep = true;
3096
- }
3097
3199
  waitForBotSays = false;
3200
+ let endOfConditionalGroup = false;
3201
+ conditionalGroupId = convoStep.logicHooks.find(lh => lh.name.startsWith('CONDITIONAL_STEP')).args[1];
3202
+ const nextConvoStep = this.conversation[i + 1];
3098
3203
  if (!nextConvoStep || nextConvoStep.sender !== 'bot' || !nextConvoStep.logicHooks || !nextConvoStep.logicHooks.some(lh => lh.name.toUpperCase().startsWith('CONDITIONAL_STEP'))) {
3099
- waitForBotSays = true;
3204
+ endOfConditionalGroup = true;
3100
3205
  } else {
3101
- const conditionalLogicHook = convoStep.logicHooks.find(lh => lh.name.startsWith('CONDITIONAL_STEP'));
3102
3206
  const nextConditionalLogicHook = nextConvoStep.logicHooks.find(lh => lh.name.startsWith('CONDITIONAL_STEP'));
3103
- waitForBotSays = conditionalLogicHook.args[1] !== nextConditionalLogicHook.args[1];
3207
+ endOfConditionalGroup = conditionalGroupId !== nextConditionalLogicHook.args[1];
3104
3208
  }
3105
- if (convoStep.conditional.skip) {
3209
+ if (convoStep.conditional.skip || conditionMetInGroup) {
3210
+ skipTranscriptStep = true;
3211
+ if (endOfConditionalGroup && !conditionMetInGroup && !convoStep.optional) {
3212
+ const failErr = new BotiumError$2(`${this.header.name}/${convoStep.stepTag}: Non of the conditions are met in ${conditionalGroupId ? `'${conditionalGroupId}' ` : ''}condition group`);
3213
+ debug$j(failErr);
3214
+ throw failErr;
3215
+ }
3216
+ if (endOfConditionalGroup) {
3217
+ waitForBotSays = !convoStep.optional;
3218
+ conditionalGroupId = undefined;
3219
+ conditionMetInGroup = false;
3220
+ }
3106
3221
  continue;
3222
+ } else {
3223
+ conditionMetInGroup = true;
3224
+ if (endOfConditionalGroup) {
3225
+ waitForBotSays = !convoStep.optional;
3226
+ conditionalGroupId = undefined;
3227
+ conditionMetInGroup = false;
3228
+ }
3107
3229
  }
3108
3230
  }
3109
3231
  if (!botMsg || !botMsg.messageText && !botMsg.media && !botMsg.buttons && !botMsg.cards && !botMsg.sourceData && !botMsg.nlp) {
@@ -3116,10 +3238,29 @@ class Convo$6 {
3116
3238
  }
3117
3239
  const isErrorHandledWithOptionConvoStep = err => {
3118
3240
  const nextConvoStep = this.conversation[i + 1];
3241
+ const retryConfig = convoStepParameters?.ignoreNotMatchedBotResponses;
3242
+ const retryOn = convoStep.sender === 'bot' && retryConfig && retryConfig.timeout && retryConfig.mainAsserter;
3119
3243
  if (convoStep.optional && nextConvoStep && nextConvoStep.sender === 'bot') {
3244
+ if (retryOn) {
3245
+ debug$j(`${this.header.name}/${convoStep.stepTag}: Retry failed asserter is ignored on optional convo`);
3246
+ }
3120
3247
  waitForBotSays = false;
3121
3248
  skipTranscriptStep = true;
3122
3249
  return true;
3250
+ } else if (retryOn) {
3251
+ if (!retryBotMessageTimeoutEnd || retryBotMessageConvoId !== convoStep.stepTag) {
3252
+ retryBotMessageTimeoutEnd = transcriptStep.stepBegin.getTime() + +retryConfig.timeout;
3253
+ retryBotMessageConvoId = convoStep.stepTag;
3254
+ }
3255
+ const now = new Date().getTime();
3256
+ const timeoutRemaining = retryBotMessageTimeoutEnd - now;
3257
+ if (timeoutRemaining > 0) {
3258
+ debug$j(`${this.header.name}/${convoStep.stepTag}: Convo step retry on, timeout remaining: ${timeoutRemaining}, error: "${err.message}"`);
3259
+ retryBotMessageDropBotResponse = true;
3260
+ return false;
3261
+ } else {
3262
+ debug$j(`${this.header.name}/${convoStep.stepTag}: Convo step retry on, but timeout is over. error: "${err.message}"`);
3263
+ }
3123
3264
  }
3124
3265
  if (container.caps[Capabilities.SCRIPTING_ENABLE_MULTIPLE_ASSERT_ERRORS]) {
3125
3266
  assertErrors.push(err);
@@ -3137,7 +3278,7 @@ class Convo$6 {
3137
3278
  const tomatch = this._resolveUtterancesToMatch(container, Object.assign({}, scriptingMemoryUpdate, scriptingMemory), messageText, botMsg);
3138
3279
  if (convoStep.not) {
3139
3280
  try {
3140
- this.scriptingEvents.assertBotNotResponse(response, tomatch, `${this.header.name}/${convoStep.stepTag}`, lastMeConvoStep);
3281
+ this.scriptingEvents.assertBotNotResponse(response, tomatch, `${this.header.name}/${convoStep.stepTag}`, lastMeConvoStep, convoStepParameters);
3141
3282
  } catch (err) {
3142
3283
  if (isErrorHandledWithOptionConvoStep(err)) {
3143
3284
  continue;
@@ -3145,7 +3286,7 @@ class Convo$6 {
3145
3286
  }
3146
3287
  } else {
3147
3288
  try {
3148
- this.scriptingEvents.assertBotResponse(response, tomatch, `${this.header.name}/${convoStep.stepTag}`, lastMeConvoStep);
3289
+ this.scriptingEvents.assertBotResponse(response, tomatch, `${this.header.name}/${convoStep.stepTag}`, lastMeConvoStep, convoStepParameters);
3149
3290
  } catch (err) {
3150
3291
  if (isErrorHandledWithOptionConvoStep(err)) {
3151
3292
  continue;
@@ -3154,7 +3295,7 @@ class Convo$6 {
3154
3295
  }
3155
3296
  } else if (convoStep.sourceData) {
3156
3297
  try {
3157
- this._compareObject(container, scriptingMemory, convoStep, botMsg.sourceData, convoStep.sourceData, botMsg);
3298
+ this._compareObject(container, scriptingMemory, convoStep, botMsg.sourceData, convoStep.sourceData, botMsg, convoStepParameters);
3158
3299
  } catch (err) {
3159
3300
  if (isErrorHandledWithOptionConvoStep(err)) {
3160
3301
  continue;
@@ -3188,19 +3329,42 @@ class Convo$6 {
3188
3329
  skipTranscriptStep = true;
3189
3330
  continue;
3190
3331
  }
3191
- const failErr = botiumErrorFromErr$1(`${this.header.name}/${convoStep.stepTag}: assertion error - ${err.message || err}`, err);
3192
- debug$j(failErr);
3193
- try {
3194
- this.scriptingEvents.fail && this.scriptingEvents.fail(failErr, lastMeConvoStep);
3195
- } catch (failErr) {}
3196
- if (container.caps[Capabilities.SCRIPTING_ENABLE_MULTIPLE_ASSERT_ERRORS] && err instanceof BotiumError$2) {
3197
- assertErrors.push(err);
3332
+ const errors = err.toArray ? err.toArray() : [];
3333
+ const retryConfig = convoStepParameters?.ignoreNotMatchedBotResponses;
3334
+ const retryOn = convoStep.sender === 'bot' && retryConfig && retryConfig.timeout && errors.length && errors.filter(({
3335
+ type,
3336
+ source,
3337
+ asserter
3338
+ }) => type === 'asserter' && (retryConfig.allAsserters || retryConfig.asserters && retryConfig.asserters.includes(asserter))).length;
3339
+ if (retryOn && (!retryBotMessageTimeoutEnd || retryBotMessageConvoId !== convoStep.stepTag)) {
3340
+ retryBotMessageTimeoutEnd = transcriptStep.stepBegin.getTime() + +retryConfig.timeout;
3341
+ retryBotMessageConvoId = convoStep.stepTag;
3342
+ }
3343
+ const now = new Date().getTime();
3344
+ const timeoutRemaining = retryOn && retryBotMessageTimeoutEnd - now;
3345
+ if (retryOn && timeoutRemaining > 0) {
3346
+ debug$j(`${this.header.name}/${convoStep.stepTag}: Convo step retry on, timeout remaining: ${timeoutRemaining}, error: "${err.message}"`);
3347
+ retryBotMessageDropBotResponse = true;
3198
3348
  } else {
3199
- throw failErr;
3349
+ if (retryOn && timeoutRemaining <= 0) {
3350
+ debug$j(`${this.header.name}/${convoStep.stepTag}: Convo step retry on, but timeout is over. error: "${err.message}"`);
3351
+ }
3352
+ const failErr = botiumErrorFromErr$1(`${this.header.name}/${convoStep.stepTag}: assertion error - ${err.message || err}`, err);
3353
+ debug$j(failErr);
3354
+ try {
3355
+ this.scriptingEvents.fail && this.scriptingEvents.fail(failErr, lastMeConvoStep);
3356
+ } catch (failErr) {}
3357
+ if (container.caps[Capabilities.SCRIPTING_ENABLE_MULTIPLE_ASSERT_ERRORS] && err instanceof BotiumError$2) {
3358
+ assertErrors.push(err);
3359
+ } else {
3360
+ throw failErr;
3361
+ }
3200
3362
  }
3201
3363
  }
3202
3364
  if (container.caps[Capabilities.SCRIPTING_ENABLE_MULTIPLE_ASSERT_ERRORS]) {
3203
3365
  if (assertErrors.length > 0) {
3366
+ // this has no effect, but logically it has to be false
3367
+ retryBotMessageDropBotResponse = false;
3204
3368
  throw botiumErrorFromList$1(assertErrors, {});
3205
3369
  }
3206
3370
  } else {
@@ -3260,7 +3424,7 @@ class Convo$6 {
3260
3424
  }
3261
3425
  }
3262
3426
  }
3263
- _compareObject(container, scriptingMemory, convoStep, result, expected, botMsg) {
3427
+ _compareObject(container, scriptingMemory, convoStep, result, expected, botMsg, convoStepParameters) {
3264
3428
  if (expected === null || expected === undefined) return;
3265
3429
  if (lodash__default["default"].isArray(expected)) {
3266
3430
  if (!lodash__default["default"].isArray(result)) {
@@ -3270,12 +3434,12 @@ class Convo$6 {
3270
3434
  throw new BotiumError$2(`${this.header.name}/${convoStep.stepTag}: bot response expected array length ${expected.length}, got ${result.length}`);
3271
3435
  }
3272
3436
  for (let i = 0; i < expected.length; i++) {
3273
- this._compareObject(container, scriptingMemory, convoStep, result[i], expected[i]);
3437
+ this._compareObject(container, scriptingMemory, convoStep, result[i], expected[i], null, convoStepParameters);
3274
3438
  }
3275
3439
  } else if (lodash__default["default"].isObject(expected)) {
3276
3440
  lodash__default["default"].forOwn(expected, (value, key) => {
3277
3441
  if (Object.prototype.hasOwnProperty.call(result, key)) {
3278
- this._compareObject(container, scriptingMemory, convoStep, result[key], expected[key]);
3442
+ this._compareObject(container, scriptingMemory, convoStep, result[key], expected[key], null, convoStepParameters);
3279
3443
  } else {
3280
3444
  throw new BotiumError$2(`${this.header.name}/${convoStep.stepTag}: bot response "${result}" missing expected property: ${key}`);
3281
3445
  }
@@ -3284,7 +3448,7 @@ class Convo$6 {
3284
3448
  ScriptingMemory.fill(container, scriptingMemory, result, expected, this.scriptingEvents);
3285
3449
  const response = this._checkNormalizeText(container, result);
3286
3450
  const tomatch = this._resolveUtterancesToMatch(container, scriptingMemory, expected, botMsg);
3287
- this.scriptingEvents.assertBotResponse(response, tomatch, `${this.header.name}/${convoStep.stepTag}`);
3451
+ this.scriptingEvents.assertBotResponse(response, tomatch, `${this.header.name}/${convoStep.stepTag}`, null, convoStepParameters);
3288
3452
  }
3289
3453
  }
3290
3454
  GetScriptingMemoryAllVariables(container) {
@@ -3344,7 +3508,7 @@ class Convo$6 {
3344
3508
  }, []);
3345
3509
  }
3346
3510
  _checkBotRepliesConsumed(container) {
3347
- if (container.caps.SCRIPTING_FORCE_BOT_CONSUMED) {
3511
+ if (container.caps[Capabilities.SCRIPTING_FORCE_BOT_CONSUMED]) {
3348
3512
  const queueLength = container._QueueLength();
3349
3513
  if (queueLength === 1) {
3350
3514
  throw new Error('There is an unread bot reply in queue');
@@ -5388,7 +5552,7 @@ var ScriptingProvider_1 = class ScriptingProvider {
5388
5552
  }) => {
5389
5553
  return this._createLogicHookPromises({
5390
5554
  hookType: 'onConvoBegin',
5391
- logicHooks: convo.beginLogicHook || [],
5555
+ logicHooks: convo?.beginLogicHook || [],
5392
5556
  convo,
5393
5557
  convoStep,
5394
5558
  scriptingMemory,
@@ -5403,7 +5567,7 @@ var ScriptingProvider_1 = class ScriptingProvider {
5403
5567
  }) => {
5404
5568
  return this._createLogicHookPromises({
5405
5569
  hookType: 'onConvoEnd',
5406
- logicHooks: convo.endLogicHook || [],
5570
+ logicHooks: convo?.endLogicHook || [],
5407
5571
  convo,
5408
5572
  convoStep,
5409
5573
  scriptingMemory,
@@ -5418,7 +5582,7 @@ var ScriptingProvider_1 = class ScriptingProvider {
5418
5582
  }) => {
5419
5583
  return this._createLogicHookPromises({
5420
5584
  hookType: 'onMeStart',
5421
- logicHooks: convoStep.logicHooks || [],
5585
+ logicHooks: convoStep?.logicHooks || [],
5422
5586
  convo,
5423
5587
  convoStep,
5424
5588
  scriptingMemory,
@@ -5433,7 +5597,7 @@ var ScriptingProvider_1 = class ScriptingProvider {
5433
5597
  }) => {
5434
5598
  return this._createLogicHookPromises({
5435
5599
  hookType: 'onMePrepare',
5436
- logicHooks: convoStep.logicHooks || [],
5600
+ logicHooks: convoStep?.logicHooks || [],
5437
5601
  convo,
5438
5602
  convoStep,
5439
5603
  scriptingMemory,
@@ -5448,7 +5612,7 @@ var ScriptingProvider_1 = class ScriptingProvider {
5448
5612
  }) => {
5449
5613
  return this._createLogicHookPromises({
5450
5614
  hookType: 'onMeEnd',
5451
- logicHooks: convoStep.logicHooks || [],
5615
+ logicHooks: convoStep?.logicHooks || [],
5452
5616
  convo,
5453
5617
  convoStep,
5454
5618
  scriptingMemory,
@@ -5463,7 +5627,7 @@ var ScriptingProvider_1 = class ScriptingProvider {
5463
5627
  }) => {
5464
5628
  return this._createLogicHookPromises({
5465
5629
  hookType: 'onBotStart',
5466
- logicHooks: convoStep.logicHooks || [],
5630
+ logicHooks: convoStep?.logicHooks || [],
5467
5631
  convo,
5468
5632
  convoStep,
5469
5633
  scriptingMemory,
@@ -5478,7 +5642,7 @@ var ScriptingProvider_1 = class ScriptingProvider {
5478
5642
  }) => {
5479
5643
  return this._createLogicHookPromises({
5480
5644
  hookType: 'onBotPrepare',
5481
- logicHooks: convoStep.logicHooks || [],
5645
+ logicHooks: convoStep?.logicHooks || [],
5482
5646
  convo,
5483
5647
  convoStep,
5484
5648
  scriptingMemory,
@@ -5493,7 +5657,7 @@ var ScriptingProvider_1 = class ScriptingProvider {
5493
5657
  }) => {
5494
5658
  return this._createLogicHookPromises({
5495
5659
  hookType: 'onBotEnd',
5496
- logicHooks: convoStep.logicHooks || [],
5660
+ logicHooks: convoStep?.logicHooks || [],
5497
5661
  convo,
5498
5662
  convoStep,
5499
5663
  scriptingMemory,
@@ -5508,7 +5672,7 @@ var ScriptingProvider_1 = class ScriptingProvider {
5508
5672
  }) => {
5509
5673
  return this._createAsserterPromises({
5510
5674
  asserterType: 'assertConvoBegin',
5511
- asserters: convo.beginAsserter || [],
5675
+ asserters: convo?.beginAsserter || [],
5512
5676
  convo,
5513
5677
  convoStep,
5514
5678
  scriptingMemory,
@@ -5523,7 +5687,7 @@ var ScriptingProvider_1 = class ScriptingProvider {
5523
5687
  }) => {
5524
5688
  return this._createAsserterPromises({
5525
5689
  asserterType: 'assertConvoStep',
5526
- asserters: convoStep.asserters || [],
5690
+ asserters: convoStep?.asserters || [],
5527
5691
  convo,
5528
5692
  convoStep,
5529
5693
  scriptingMemory,
@@ -5538,7 +5702,7 @@ var ScriptingProvider_1 = class ScriptingProvider {
5538
5702
  }) => {
5539
5703
  return this._createAsserterPromises({
5540
5704
  asserterType: 'assertConvoEnd',
5541
- asserters: convo.endAsserter || [],
5705
+ asserters: convo?.endAsserter || [],
5542
5706
  convo,
5543
5707
  convoStep,
5544
5708
  scriptingMemory,
@@ -5567,12 +5731,13 @@ var ScriptingProvider_1 = class ScriptingProvider {
5567
5731
  resolveEmptyIfUnknown
5568
5732
  });
5569
5733
  },
5570
- assertBotResponse: (botresponse, tomatch, stepTag, meMsg) => {
5734
+ assertBotResponse: (botresponse, tomatch, stepTag, meMsg, convoStepParameters) => {
5571
5735
  if (!lodash__default["default"].isArray(tomatch)) {
5572
5736
  tomatch = [tomatch];
5573
5737
  }
5574
5738
  debug$9(`assertBotResponse ${stepTag} ${meMsg ? `(${meMsg}) ` : ''}BOT: ${botresponse} = ${tomatch} ...`);
5575
- const found = lodash__default["default"].find(tomatch, utt => this.matchFn(botresponse, utt, this.caps[Capabilities.SCRIPTING_MATCHING_MODE_ARGS]));
5739
+ const matchFn = convoStepParameters.matchingMode ? getMatchFunction(convoStepParameters.matchingMode) || this.matchFn : this.matchFn;
5740
+ const found = lodash__default["default"].find(tomatch, utt => matchFn(botresponse, utt, this.caps[Capabilities.SCRIPTING_MATCHING_MODE_ARGS]));
5576
5741
  const asserterType = this.caps[Capabilities.SCRIPTING_MATCHING_MODE] === 'wer' ? 'Word Error Rate Asserter' : 'Text Match Asserter';
5577
5742
  if (lodash__default["default"].isNil(found)) {
5578
5743
  if (this.caps[Capabilities.SCRIPTING_MATCHING_MODE] === 'wer') {
@@ -5622,12 +5787,13 @@ var ScriptingProvider_1 = class ScriptingProvider {
5622
5787
  }
5623
5788
  }
5624
5789
  },
5625
- assertBotNotResponse: (botresponse, nottomatch, stepTag, meMsg) => {
5790
+ assertBotNotResponse: (botresponse, nottomatch, stepTag, meMsg, convoStepParameters) => {
5626
5791
  if (!lodash__default["default"].isArray(nottomatch)) {
5627
5792
  nottomatch = [nottomatch];
5628
5793
  }
5629
5794
  debug$9(`assertBotNotResponse ${stepTag} ${meMsg ? `(${meMsg}) ` : ''}BOT: ${botresponse} != ${nottomatch} ...`);
5630
- const found = lodash__default["default"].find(nottomatch, utt => this.matchFn(botresponse, utt, this.caps[Capabilities.SCRIPTING_MATCHING_MODE_ARGS]));
5795
+ const matchFn = convoStepParameters.matchingMode ? getMatchFunction(convoStepParameters.matchingMode) || this.matchFn : this.matchFn;
5796
+ const found = lodash__default["default"].find(nottomatch, utt => matchFn(botresponse, utt, this.caps[Capabilities.SCRIPTING_MATCHING_MODE_ARGS]));
5631
5797
  const asserterType = this.caps[Capabilities.SCRIPTING_MATCHING_MODE] === 'wer' ? 'Word Error Rate Asserter' : 'Text Match Asserter';
5632
5798
  if (!lodash__default["default"].isNil(found)) {
5633
5799
  if (this.caps[Capabilities.SCRIPTING_MATCHING_MODE] === 'wer') {
@@ -5701,6 +5867,22 @@ var ScriptingProvider_1 = class ScriptingProvider {
5701
5867
  assertConvoStep: 'assertNotConvoStep',
5702
5868
  assertConvoEnd: 'assertNotConvoEnd'
5703
5869
  };
5870
+ const updateExceptionContext = (promise, asserter) => {
5871
+ const updateError = err => {
5872
+ if (err instanceof BotiumError$1) {
5873
+ if (!err.context) {
5874
+ err.context = {};
5875
+ }
5876
+ err.context.asserter = asserter.name;
5877
+ throw err;
5878
+ } else {
5879
+ throw botiumErrorFromErr(lodash__default["default"].isString(err) ? err : err.message, err, {
5880
+ asserter: asserter.name
5881
+ });
5882
+ }
5883
+ };
5884
+ return promise.catch(err => updateError(err));
5885
+ };
5704
5886
  const callAsserter = (asserterSpec, asserter, params) => {
5705
5887
  if (asserterSpec.not) {
5706
5888
  const notAsserterType = mapNot[asserterType];
@@ -5724,24 +5906,36 @@ var ScriptingProvider_1 = class ScriptingProvider {
5724
5906
  return p(this.retryHelperAsserter, () => asserter[asserterType](params));
5725
5907
  }
5726
5908
  };
5727
- const convoAsserter = asserters.filter(a => this.asserters[a.name][asserterType]).map(a => callAsserter(a, this.asserters[a.name], {
5728
- convo,
5729
- convoStep,
5730
- scriptingMemory,
5731
- container,
5732
- args: ScriptingMemory.applyToArgs(a.args, scriptingMemory, container.caps, rest.botMsg),
5733
- isGlobal: false,
5734
- ...rest
5735
- }));
5736
- const globalAsserter = Object.values(this.globalAsserter).filter(a => a[asserterType]).map(a => p(this.retryHelperAsserter, () => a[asserterType]({
5737
- convo,
5738
- convoStep,
5739
- scriptingMemory,
5740
- container,
5741
- args: [],
5742
- isGlobal: true,
5743
- ...rest
5744
- })));
5909
+ const convoAsserter = asserters.filter(a => this.asserters[a.name][asserterType]).map(a => ({
5910
+ asserter: a,
5911
+ promise: callAsserter(a, this.asserters[a.name], {
5912
+ convo,
5913
+ convoStep,
5914
+ scriptingMemory,
5915
+ container,
5916
+ args: ScriptingMemory.applyToArgs(a.args, scriptingMemory, container.caps, rest.botMsg),
5917
+ isGlobal: false,
5918
+ ...rest
5919
+ })
5920
+ })).map(({
5921
+ promise,
5922
+ asserter
5923
+ }) => updateExceptionContext(promise, asserter));
5924
+ const globalAsserter = Object.values(this.globalAsserter).filter(a => a[asserterType]).map(a => ({
5925
+ asserter: a,
5926
+ promise: p(this.retryHelperAsserter, () => a[asserterType]({
5927
+ convo,
5928
+ convoStep,
5929
+ scriptingMemory,
5930
+ container,
5931
+ args: [],
5932
+ isGlobal: true,
5933
+ ...rest
5934
+ }))
5935
+ })).map(({
5936
+ promise,
5937
+ asserter
5938
+ }) => updateExceptionContext(promise, asserter));
5745
5939
  const allPromises = [...convoAsserter, ...globalAsserter];
5746
5940
  if (this.caps[Capabilities.SCRIPTING_ENABLE_MULTIPLE_ASSERT_ERRORS]) {
5747
5941
  return Promise.allSettled(allPromises).then(results => {
@@ -5767,7 +5961,8 @@ var ScriptingProvider_1 = class ScriptingProvider {
5767
5961
  if (hookType !== 'onMeStart' && hookType !== 'onMePrepare' && hookType !== 'onMeEnd' && hookType !== 'onBotStart' && hookType !== 'onBotPrepare' && hookType !== 'onBotEnd' && hookType !== 'onConvoBegin' && hookType !== 'onConvoEnd') {
5768
5962
  throw Error(`Unknown hookType ${hookType}`);
5769
5963
  }
5770
- const convoStepPromises = (logicHooks || []).filter(l => this.logicHooks[l.name][hookType]).map(l => p(this.retryHelperLogicHook, () => this.logicHooks[l.name][hookType]({
5964
+ const localHooks = (logicHooks || []).filter(l => this.logicHooks[l.name][hookType]);
5965
+ const convoStepPromises = localHooks.map(l => p(this.retryHelperLogicHook, () => this.logicHooks[l.name][hookType]({
5771
5966
  convo,
5772
5967
  convoStep,
5773
5968
  scriptingMemory,
@@ -5776,7 +5971,8 @@ var ScriptingProvider_1 = class ScriptingProvider {
5776
5971
  isGlobal: false,
5777
5972
  ...rest
5778
5973
  })));
5779
- const globalPromises = Object.values(this.globalLogicHook).filter(l => l[hookType]).map(l => p(this.retryHelperLogicHook, () => l[hookType]({
5974
+ const globalHooks = Object.values(this.globalLogicHook).filter(l => l[hookType]);
5975
+ const globalPromises = globalHooks.map(l => p(this.retryHelperLogicHook, () => l[hookType]({
5780
5976
  convo,
5781
5977
  convoStep,
5782
5978
  scriptingMemory,
@@ -5786,7 +5982,14 @@ var ScriptingProvider_1 = class ScriptingProvider {
5786
5982
  ...rest
5787
5983
  })));
5788
5984
  const allPromises = [...convoStepPromises, ...globalPromises];
5789
- if (allPromises.length > 0) return Promise.all(allPromises).then(() => true);
5985
+ if (allPromises.length > 0) {
5986
+ return Promise.all(allPromises).then(() => {
5987
+ return {
5988
+ // just returning some humanreadable
5989
+ hooks: [...localHooks, ...globalHooks].map(h => h.name || h.context?.ref || JSON.stringify(h))
5990
+ };
5991
+ });
5992
+ }
5790
5993
  return Promise.resolve(false);
5791
5994
  }
5792
5995
  _createUserInputPromises({
@@ -5796,7 +5999,7 @@ var ScriptingProvider_1 = class ScriptingProvider {
5796
5999
  container,
5797
6000
  ...rest
5798
6001
  }) {
5799
- const convoStepPromises = (convoStep.userInputs || []).filter(ui => this.userInputs[ui.name]).map(ui => p(this.retryHelperUserInput, () => this.userInputs[ui.name].setUserInput({
6002
+ const convoStepPromises = (convoStep?.userInputs || []).filter(ui => this.userInputs[ui.name]).map(ui => p(this.retryHelperUserInput, () => this.userInputs[ui.name].setUserInput({
5800
6003
  convo,
5801
6004
  convoStep,
5802
6005
  scriptingMemory,
@@ -5858,6 +6061,11 @@ var ScriptingProvider_1 = class ScriptingProvider {
5858
6061
  }
5859
6062
  };
5860
6063
  }
6064
+
6065
+ // Livechat, and crawler using logichooks too. So they need script context
6066
+ BuildScriptContext() {
6067
+ return this._buildScriptContext();
6068
+ }
5861
6069
  Build() {
5862
6070
  const CompilerXlsx = CompilerXlsx_1;
5863
6071
  this.compilers[Constants.SCRIPTING_FORMAT_XSLX] = new CompilerXlsx(this._buildScriptContext(), this.caps);