botium-core 1.13.4 → 1.13.6

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 (70) hide show
  1. package/dist/botium-cjs.js +262 -88
  2. package/dist/botium-cjs.js.map +1 -1
  3. package/dist/botium-es.js +262 -88
  4. package/dist/botium-es.js.map +1 -1
  5. package/package.json +19 -19
  6. package/src/helpers/RetryHelper.js +3 -2
  7. package/src/scripting/CompilerXlsx.js +1 -0
  8. package/src/scripting/MatchFunctions.js +3 -1
  9. package/src/scripting/ScriptingMemory.js +41 -2
  10. package/src/scripting/ScriptingProvider.js +164 -56
  11. package/src/scripting/helper.js +2 -0
  12. package/src/scripting/logichook/asserter/BotRepliesConsumedAsserter.js +1 -1
  13. package/src/scripting/logichook/asserter/BotRepliesUnconsumedCountAsserter.js +1 -1
  14. package/src/scripting/logichook/asserter/ButtonsAsserter.js +1 -1
  15. package/src/scripting/logichook/asserter/ButtonsCountAsserter.js +1 -1
  16. package/src/scripting/logichook/asserter/ButtonsCountRecAsserter.js +1 -1
  17. package/src/scripting/logichook/asserter/CardsAsserter.js +1 -1
  18. package/src/scripting/logichook/asserter/CardsCountAsserter.js +1 -1
  19. package/src/scripting/logichook/asserter/CardsCountRecAsserter.js +1 -1
  20. package/src/scripting/logichook/asserter/EntitiesAsserter.js +1 -1
  21. package/src/scripting/logichook/asserter/EntityContentAsserter.js +2 -2
  22. package/src/scripting/logichook/asserter/EntityValuesAsserter.js +1 -1
  23. package/src/scripting/logichook/asserter/FormsAsserter.js +1 -1
  24. package/src/scripting/logichook/asserter/IntentAsserter.js +3 -3
  25. package/src/scripting/logichook/asserter/IntentConfidenceAsserter.js +4 -4
  26. package/src/scripting/logichook/asserter/IntentUniqueAsserter.js +2 -2
  27. package/src/scripting/logichook/asserter/JsonPathAsserter.js +5 -5
  28. package/src/scripting/logichook/asserter/JsonPathCountAsserter.js +2 -2
  29. package/src/scripting/logichook/asserter/MediaAsserter.js +1 -1
  30. package/src/scripting/logichook/asserter/MediaCountAsserter.js +1 -1
  31. package/src/scripting/logichook/asserter/MediaCountRecAsserter.js +1 -1
  32. package/src/scripting/logichook/asserter/PauseAsserter.js +1 -1
  33. package/src/scripting/logichook/asserter/ResponseLengthAsserter.js +3 -2
  34. package/src/scripting/logichook/asserter/TextContainsAllAsserter.js +2 -1
  35. package/src/scripting/logichook/asserter/TextContainsAllICAsserter.js +2 -1
  36. package/src/scripting/logichook/asserter/TextContainsAnyAsserter.js +1 -0
  37. package/src/scripting/logichook/asserter/TextContainsAnyICAsserter.js +2 -1
  38. package/src/scripting/logichook/asserter/TextEqualsAnyAsserter.js +2 -1
  39. package/src/scripting/logichook/asserter/TextEqualsAnyICAsserter.js +2 -1
  40. package/src/scripting/logichook/asserter/TextRegexpAllAsserter.js +2 -1
  41. package/src/scripting/logichook/asserter/TextRegexpAllICAsserter.js +2 -1
  42. package/src/scripting/logichook/asserter/TextRegexpAnyAsserter.js +1 -0
  43. package/src/scripting/logichook/asserter/TextRegexpAnyICAsserter.js +2 -1
  44. package/src/scripting/logichook/asserter/TextWildcardAllAsserter.js +2 -1
  45. package/src/scripting/logichook/asserter/TextWildcardAllICAsserter.js +2 -1
  46. package/src/scripting/logichook/asserter/TextWildcardAnyAsserter.js +1 -0
  47. package/src/scripting/logichook/asserter/TextWildcardAnyICAsserter.js +2 -1
  48. package/src/scripting/logichook/asserter/TextWildcardExactAllAsserter.js +2 -1
  49. package/src/scripting/logichook/asserter/TextWildcardExactAllICAsserter.js +2 -1
  50. package/src/scripting/logichook/asserter/TextWildcardExactAnyAsserter.js +1 -0
  51. package/src/scripting/logichook/asserter/TextWildcardExactAnyICAsserter.js +2 -1
  52. package/src/scripting/logichook/asserter/WerAsserter.js +10 -8
  53. package/src/scripting/logichook/userinput/MediaInput.js +2 -1
  54. package/test/compiler/compilercsv.spec.js +9 -2
  55. package/test/compiler/convos/csv/utterances_variable_row_len.csv +1 -1
  56. package/test/convo/fillAndApplyScriptingMemory.spec.js +64 -4
  57. package/test/convo/transcript.spec.js +15 -6
  58. package/test/scripting/asserters/convos/{wer_threshold_nok.yml → wer_threshold_nok_float.yml} +0 -0
  59. package/test/scripting/asserters/convos/wer_threshold_nok_percentage.yml +7 -0
  60. package/test/scripting/asserters/convos/{wer_threshold_ok.yml → wer_threshold_ok_float.yml} +0 -0
  61. package/test/scripting/asserters/convos/wer_threshold_ok_percentage.yml +7 -0
  62. package/test/scripting/asserters/entityContentAsserter.spec.js +2 -7
  63. package/test/scripting/asserters/intentAsserter.spec.js +1 -1
  64. package/test/scripting/asserters/intentConfidenceAsserter.spec.js +3 -7
  65. package/test/scripting/asserters/jsonpathAsserter.spec.js +1 -1
  66. package/test/scripting/asserters/werAsserter.spec.js +25 -5
  67. package/test/scripting/matching/matchingmode.spec.js +42 -2
  68. package/test/scripting/scriptingModificator.spec.js +1 -2
  69. package/test/scripting/scriptingProvider.spec.js +156 -4
  70. package/test/scripting/utteranceexpansion/associateByIndex.spec.js +15 -15
package/dist/botium-es.js CHANGED
@@ -37,7 +37,7 @@ import express from 'express';
37
37
  import bodyParser from 'body-parser';
38
38
 
39
39
  var name = "botium-core";
40
- var version$1 = "1.13.4";
40
+ var version$1 = "1.13.6";
41
41
  var description = "The Selenium for Chatbots";
42
42
  var main = "index.js";
43
43
  var module = "dist/botium-es.js";
@@ -69,7 +69,7 @@ var bugs = {
69
69
  };
70
70
  var homepage = "https://www.botium.ai";
71
71
  var dependencies = {
72
- "@babel/runtime": "^7.18.6",
72
+ "@babel/runtime": "^7.19.0",
73
73
  async: "^3.2.4",
74
74
  "body-parser": "^1.20.0",
75
75
  boolean: "^3.2.0",
@@ -79,7 +79,7 @@ var dependencies = {
79
79
  esprima: "^4.0.1",
80
80
  express: "^4.18.1",
81
81
  globby: "11.0.4",
82
- ioredis: "^5.1.0",
82
+ ioredis: "^5.2.3",
83
83
  "is-class": "^0.0.9",
84
84
  "is-json": "^2.0.1",
85
85
  jsonpath: "^1.1.1",
@@ -96,13 +96,13 @@ var dependencies = {
96
96
  rimraf: "^3.0.2",
97
97
  "sanitize-filename": "^1.6.3",
98
98
  slugify: "^1.6.5",
99
- "socket.io": "^4.5.1",
100
- "socket.io-client": "^4.5.1",
99
+ "socket.io": "^4.5.2",
100
+ "socket.io-client": "^4.5.2",
101
101
  "socketio-auth": "^0.1.1",
102
- "swagger-jsdoc": "^6.2.1",
103
- "swagger-ui-express": "^4.4.0",
104
- uuid: "^8.3.2",
105
- vm2: "^3.9.10",
102
+ "swagger-jsdoc": "^6.2.5",
103
+ "swagger-ui-express": "^4.5.0",
104
+ uuid: "^9.0.0",
105
+ vm2: "^3.9.11",
106
106
  "word-error-rate": "0.0.7",
107
107
  "write-yaml": "^1.0.0",
108
108
  xlsx: "^0.18.5",
@@ -110,27 +110,27 @@ var dependencies = {
110
110
  yaml: "^2.1.1"
111
111
  };
112
112
  var devDependencies = {
113
- "@babel/core": "^7.18.6",
114
- "@babel/node": "^7.18.6",
115
- "@babel/plugin-transform-runtime": "^7.18.6",
116
- "@babel/preset-env": "^7.18.6",
113
+ "@babel/core": "^7.19.3",
114
+ "@babel/node": "^7.19.1",
115
+ "@babel/plugin-transform-runtime": "^7.19.1",
116
+ "@babel/preset-env": "^7.19.3",
117
117
  chai: "^4.3.6",
118
118
  "chai-as-promised": "^7.1.1",
119
119
  "cross-env": "^7.0.3",
120
- eslint: "^8.19.0",
120
+ eslint: "^8.24.0",
121
121
  "eslint-config-standard": "^17.0.0",
122
122
  "eslint-plugin-import": "^2.26.0",
123
123
  "eslint-plugin-mocha": "^10.1.0",
124
- "eslint-plugin-n": "^15.2.4",
125
- "eslint-plugin-promise": "^6.0.0",
124
+ "eslint-plugin-n": "^15.3.0",
125
+ "eslint-plugin-promise": "^6.0.1",
126
126
  "eslint-plugin-standard": "^4.1.0",
127
127
  "license-checker": "^25.0.1",
128
128
  "license-compatibility-checker": "^0.3.5",
129
129
  mocha: "^10.0.0",
130
- nock: "^13.2.8",
131
- "npm-check-updates": "^15.2.6",
130
+ nock: "^13.2.9",
131
+ "npm-check-updates": "^16.3.4",
132
132
  nyc: "^15.1.0",
133
- rollup: "^2.76.0",
133
+ rollup: "^2.79.1",
134
134
  "rollup-plugin-babel": "^4.4.0",
135
135
  "rollup-plugin-commonjs": "^10.1.0",
136
136
  "rollup-plugin-json": "^4.0.0",
@@ -2271,6 +2271,8 @@ const convoStepToLines$2 = step => {
2271
2271
  lines.push('MEDIA ' + step.media[0].mediaUri);
2272
2272
  } else if (step.messageText) {
2273
2273
  lines.push(step.messageText);
2274
+ } else if (step.sourceData) {
2275
+ lines.push(JSON.stringify(step.sourceData, null, 2));
2274
2276
  }
2275
2277
 
2276
2278
  step.userInputs && step.userInputs.forEach(userInput => {
@@ -2463,6 +2465,34 @@ const SCRIPTING_FUNCTIONS_RAW = {
2463
2465
  $timestamp: () => {
2464
2466
  return Date.now();
2465
2467
  },
2468
+ $tomorrow: pattern => {
2469
+ if (pattern) {
2470
+ return moment().add(1, 'day').format(pattern);
2471
+ }
2472
+
2473
+ return moment().add(1, 'day').toDate().toLocaleDateString();
2474
+ },
2475
+ $yesterday: pattern => {
2476
+ if (pattern) {
2477
+ return moment().subtract(1, 'day').format(pattern);
2478
+ }
2479
+
2480
+ return moment().subtract(1, 'day').toDate().toLocaleDateString();
2481
+ },
2482
+ $date_add: (amount, unit, pattern) => {
2483
+ if (pattern) {
2484
+ return moment().add(amount, unit).format(pattern);
2485
+ }
2486
+
2487
+ return moment().add(amount, unit).toDate().toLocaleDateString();
2488
+ },
2489
+ $date_subtract: (amount, unit, pattern) => {
2490
+ if (pattern) {
2491
+ return moment().subtract(amount, unit).format(pattern);
2492
+ }
2493
+
2494
+ return moment().subtract(amount, unit).toDate().toLocaleDateString();
2495
+ },
2466
2496
  $year: () => {
2467
2497
  return new Date().getFullYear();
2468
2498
  },
@@ -2554,7 +2584,8 @@ const SCRIPTING_FUNCTIONS_RAW = {
2554
2584
  require: false,
2555
2585
  env: caps[Capabilities.SECURITY_ALLOW_UNSAFE] ? process.env : {},
2556
2586
  sandbox: {
2557
- caps
2587
+ caps,
2588
+ moment
2558
2589
  }
2559
2590
  });
2560
2591
  return vm.run(`module.exports = (${code})`);
@@ -2632,7 +2663,22 @@ const _apply = (scriptingMemory, str, caps, mockMsg) => {
2632
2663
  for (const match of matches) {
2633
2664
  if (match.indexOf('(') > 0) {
2634
2665
  const arg = match.substring(match.indexOf('(') + 1, match.lastIndexOf(')')).replace(/\\\)/g, ')');
2635
- str = str.replace(match, SCRIPTING_FUNCTIONS$1[key].handler(caps, arg, mockMsg));
2666
+ let args = [arg];
2667
+
2668
+ if (SCRIPTING_FUNCTIONS$1[key].numberOfArguments > 1) {
2669
+ args = arg.split(',');
2670
+ }
2671
+
2672
+ args = args.map(arg => {
2673
+ arg = arg.trim();
2674
+
2675
+ if (arg.startsWith('"') && arg.endsWith('"')) {
2676
+ return arg.substring(1, arg.length - 1);
2677
+ } else {
2678
+ return arg;
2679
+ }
2680
+ });
2681
+ str = str.replace(match, SCRIPTING_FUNCTIONS$1[key].handler(caps, ...args, mockMsg));
2636
2682
  } else {
2637
2683
  str = str.replace(match, SCRIPTING_FUNCTIONS$1[key].handler(caps));
2638
2684
  }
@@ -2743,7 +2789,10 @@ var RetryHelper_1 = class RetryHelper {
2743
2789
  factor: caps[`RETRY_${section.toUpperCase()}_FACTOR`] || (lodash.isNil(options.factor) ? 1 : options.factor),
2744
2790
  minTimeout: caps[`RETRY_${section.toUpperCase()}_MINTIMEOUT`] || (lodash.isNil(options.minTimeout) ? 1000 : options.minTimeout)
2745
2791
  };
2746
- debug$j(`Retry for ${section} is ${this.retrySettings.retries > 0 ? 'enabled' : 'disabled'}. Settings: ${JSON.stringify(this.retrySettings)} Patterns: ${JSON.stringify(this.retryErrorPatterns.map(r => r.toString()))}`);
2792
+
2793
+ if (this.retrySettings.retries > 0) {
2794
+ debug$j(`Retry for ${section} is enabled. Settings: ${JSON.stringify(this.retrySettings)} Patterns: ${JSON.stringify(this.retryErrorPatterns.map(r => r.toString()))}`);
2795
+ }
2747
2796
  }
2748
2797
 
2749
2798
  shouldRetry(err) {
@@ -3781,7 +3830,8 @@ const equals = ignoreCase => (botresponse, utterance) => {
3781
3830
  const wer = () => (botresponse, utterance, args) => {
3782
3831
  botresponse = _normalize(botresponse || '');
3783
3832
  utterance = toString(utterance || '');
3784
- return wordErrorRate.wordErrorRate(botresponse, utterance) <= args[0];
3833
+ const threshold = [',', '.'].find(p => `${args[0]}`.includes(p)) ? parseFloat(args[0]) : parseInt(args[0]) / 100;
3834
+ return wordErrorRate.wordErrorRate(botresponse, utterance) <= threshold;
3785
3835
  };
3786
3836
 
3787
3837
  const getMatchFunction$1 = matchingMode => {
@@ -4831,7 +4881,8 @@ var CompilerXlsx_1 = class CompilerXlsx extends CompilerBase_1 {
4831
4881
  convoResults.forEach(convo => {
4832
4882
  if (!convo.header.name) {
4833
4883
  convo.header.name = `${convo.header.sheetname}-${this.colnames[convo.header.colindex]}${formatRowIndex(convo.header.rowindex)}`;
4834
- }
4884
+ } // it is not used anymore?
4885
+
4835
4886
 
4836
4887
  convo.header.sort = convo.header.name;
4837
4888
  scriptResults.push(convo);
@@ -6175,7 +6226,7 @@ var ScriptingProvider_1 = class ScriptingProvider {
6175
6226
 
6176
6227
  const found = lodash.find(tomatch, utt => this.matchFn(botresponse, utt, this.caps[Capabilities.SCRIPTING_MATCHING_MODE_ARGS]));
6177
6228
 
6178
- const asserterType = this.caps[Capabilities.SCRIPTING_MATCHING_MODE] === 'wer' ? 'WerAsserter' : 'TextMatchAsserter';
6229
+ const asserterType = this.caps[Capabilities.SCRIPTING_MATCHING_MODE] === 'wer' ? 'Word Error Rate Asserter' : 'Text Match Asserter';
6179
6230
 
6180
6231
  if (lodash.isNil(found)) {
6181
6232
  let message = `${stepTag}: Bot response `;
@@ -6187,13 +6238,18 @@ var ScriptingProvider_1 = class ScriptingProvider {
6187
6238
  throw new BotiumError$2(message, {
6188
6239
  type: 'asserter',
6189
6240
  source: asserterType,
6241
+ params: {
6242
+ matchingMode: this.caps[Capabilities.SCRIPTING_MATCHING_MODE],
6243
+ args: this.caps[Capabilities.SCRIPTING_MATCHING_MODE_ARGS] || null
6244
+ },
6190
6245
  context: {
6191
6246
  stepTag
6192
6247
  },
6193
6248
  cause: {
6194
6249
  expected: tomatch,
6195
6250
  actual: botresponse,
6196
- matchingMode: this.caps[Capabilities.SCRIPTING_MATCHING_MODE]
6251
+ matchingMode: this.caps[Capabilities.SCRIPTING_MATCHING_MODE],
6252
+ args: this.caps[Capabilities.SCRIPTING_MATCHING_MODE_ARGS] || null
6197
6253
  }
6198
6254
  });
6199
6255
  }
@@ -6207,7 +6263,7 @@ var ScriptingProvider_1 = class ScriptingProvider {
6207
6263
 
6208
6264
  const found = lodash.find(nottomatch, utt => this.matchFn(botresponse, utt, this.caps[Capabilities.SCRIPTING_MATCHING_MODE_ARGS]));
6209
6265
 
6210
- const asserterType = this.caps[Capabilities.SCRIPTING_MATCHING_MODE] === 'wer' ? 'WerAsserter' : 'TextMatchAsserter';
6266
+ const asserterType = this.caps[Capabilities.SCRIPTING_MATCHING_MODE] === 'wer' ? 'Word Error Rate Asserter' : 'Text Match Asserter';
6211
6267
 
6212
6268
  if (!lodash.isNil(found)) {
6213
6269
  let message = `${stepTag}: Bot response `;
@@ -6219,6 +6275,10 @@ var ScriptingProvider_1 = class ScriptingProvider {
6219
6275
  throw new BotiumError$2(message, {
6220
6276
  type: 'asserter',
6221
6277
  source: asserterType,
6278
+ params: {
6279
+ matchingMode: this.caps[Capabilities.SCRIPTING_MATCHING_MODE],
6280
+ args: this.caps[Capabilities.SCRIPTING_MATCHING_MODE_ARGS] || null
6281
+ },
6222
6282
  context: {
6223
6283
  stepTag
6224
6284
  },
@@ -6226,7 +6286,8 @@ var ScriptingProvider_1 = class ScriptingProvider {
6226
6286
  not: true,
6227
6287
  expected: nottomatch,
6228
6288
  actual: botresponse,
6229
- matchingMode: this.caps[Capabilities.SCRIPTING_MATCHING_MODE]
6289
+ matchingMode: this.caps[Capabilities.SCRIPTING_MATCHING_MODE],
6290
+ args: this.caps[Capabilities.SCRIPTING_MATCHING_MODE_ARGS] || null
6230
6291
  }
6231
6292
  });
6232
6293
  }
@@ -7006,30 +7067,77 @@ var ScriptingProvider_1 = class ScriptingProvider {
7006
7067
  this._sortConvos();
7007
7068
  }
7008
7069
 
7009
- ExpandConvos() {
7070
+ ExpandConvos(options = {}) {
7071
+ options = Object.assign({
7072
+ // use skip and keep, or justHeader
7073
+ justHeader: false,
7074
+ // drop unwanted convos
7075
+ convoFilter: null
7076
+ }, options);
7077
+ const context = {
7078
+ count: 0
7079
+ };
7010
7080
  const expandedConvos = [];
7011
7081
  debug$9(`ExpandConvos - Using utterances expansion mode: ${this.caps[Capabilities.SCRIPTING_UTTEXPANSION_MODE]}`);
7012
7082
  this.convos.forEach(convo => {
7013
7083
  convo.expandPartialConvos();
7014
7084
 
7015
- this._expandConvo(expandedConvos, convo);
7085
+ for (const expanded of this._expandConvo(convo, options, context)) {
7086
+ expanded.header.assertionCount = this.GetAssertionCount(expanded);
7087
+
7088
+ if (options.justHeader) {
7089
+ const ConvoWithOnlyHeader = {
7090
+ header: {
7091
+ name: expanded.header.name,
7092
+ assertionCount: expanded.header.assertionCount
7093
+ }
7094
+ };
7095
+ expandedConvos.push(ConvoWithOnlyHeader);
7096
+ } else {
7097
+ expandedConvos.push(expanded);
7098
+ }
7099
+ }
7016
7100
  });
7017
7101
  this.convos = expandedConvos;
7018
7102
 
7019
- this._sortConvos();
7103
+ if (!options.justHeader) {
7104
+ this._sortConvos();
7105
+ } else {
7106
+ this._updateConvos();
7107
+ }
7108
+ }
7109
+
7110
+ ExpandConvosIterable(options = {}) {
7111
+ options = Object.assign({
7112
+ // drop unwanted convos
7113
+ convoFilter: null
7114
+ }, options);
7115
+ debug$9(`ExpandConvos - Using utterances expansion mode: ${this.caps[Capabilities.SCRIPTING_UTTEXPANSION_MODE]}`); // creating a nested generator, calling the other.
7116
+ // We hope this.convos does not changes while this iterator is used
7117
+
7118
+ const _convosIterable = function* (options) {
7119
+ const context = {
7120
+ count: 0
7121
+ };
7122
+
7123
+ for (const convo of this.convos) {
7124
+ convo.expandPartialConvos();
7125
+ yield* this._expandConvo(convo, options, context);
7126
+ }
7127
+ }.bind(this);
7128
+
7129
+ this.convosIterable = _convosIterable(options);
7020
7130
  }
7021
7131
  /**
7022
- *
7023
- * @param expandedConvos
7132
+ * This is a generator function with yield
7024
7133
  * @param currentConvo
7025
7134
  * @param convoStepIndex
7026
7135
  * @param convoStepsStack list of ConvoSteps
7027
- * @param context {width: }
7028
7136
  * @private
7029
7137
  */
7030
7138
 
7031
7139
 
7032
- _expandConvo(expandedConvos, currentConvo, convoStepIndex = 0, convoStepsStack = [], context = {}) {
7140
+ *_expandConvo(currentConvo, options, context, convoStepIndex = 0, convoStepsStack = []) {
7033
7141
  const utterancePostfix = (lineTag, uttOrUserInput) => {
7034
7142
  const naming = this.caps[Capabilities.SCRIPTING_UTTEXPANSION_NAMING_MODE] || Defaults$1.capabilities[Capabilities.SCRIPTING_UTTEXPANSION_NAMING_MODE];
7035
7143
 
@@ -7055,8 +7163,7 @@ var ScriptingProvider_1 = class ScriptingProvider {
7055
7163
  if (currentStep.sender === 'bot' || currentStep.sender === 'begin' || currentStep.sender === 'end') {
7056
7164
  const currentStepsStack = convoStepsStack.slice();
7057
7165
  currentStepsStack.push(lodash.cloneDeep(currentStep));
7058
-
7059
- this._expandConvo(expandedConvos, currentConvo, convoStepIndex + 1, currentStepsStack, context);
7166
+ yield* this._expandConvo(currentConvo, options, context, convoStepIndex + 1, currentStepsStack);
7060
7167
  } else if (currentStep.sender === 'me') {
7061
7168
  let useUnexpanded = true;
7062
7169
 
@@ -7078,16 +7185,15 @@ var ScriptingProvider_1 = class ScriptingProvider {
7078
7185
  if (this.utterances[uttName]) {
7079
7186
  const allutterances = this.utterances[uttName].utterances;
7080
7187
 
7081
- const processSampleUtterances = (sampleutterances, myContext) => {
7082
- sampleutterances.forEach((utt, index) => {
7083
- processSampleUtterance(utt, sampleutterances.length, index, Object.assign({
7188
+ const processSampleUtterances = function* (sampleutterances, myContext) {
7189
+ for (let index = 0; index < sampleutterances.length; index++) {
7190
+ yield* processSampleUtterance(sampleutterances[index], sampleutterances.length, index, Object.assign({
7084
7191
  indexExpansionModeIndex: index
7085
7192
  }, myContext || context));
7086
- });
7193
+ }
7087
7194
  };
7088
7195
 
7089
- const processSampleUtterance = (sampleutterance, length, index, myContext) => {
7090
- const lineTag = `${index + 1}`.padStart(`${length}`.length, '0');
7196
+ const processSampleUtterance = function* (sampleutterance, length, index, myContext) {
7091
7197
  const currentStepsStack = convoStepsStack.slice();
7092
7198
 
7093
7199
  if (uttArgs) {
@@ -7100,19 +7206,24 @@ var ScriptingProvider_1 = class ScriptingProvider {
7100
7206
 
7101
7207
  const currentConvoLabeled = lodash.cloneDeep(currentConvo);
7102
7208
 
7103
- Object.assign(currentConvoLabeled.header, {
7104
- name: `${currentConvo.header.name}/${uttName}-${utterancePostfix(lineTag, sampleutterance)}`
7105
- });
7209
+ if (length > 1) {
7210
+ const lineTag = `${index + 1}`.padStart(`${length}`.length, '0');
7211
+ Object.assign(currentConvoLabeled.header, {
7212
+ name: `${currentConvo.header.name}/${uttName}-${utterancePostfix(lineTag, sampleutterance)}`
7213
+ });
7214
+ }
7215
+
7106
7216
  if (!currentConvoLabeled.sourceTag) currentConvoLabeled.sourceTag = {};
7107
7217
  if (!currentConvoLabeled.sourceTag.origConvoName) currentConvoLabeled.sourceTag.origConvoName = currentConvo.header.name;
7218
+ yield* this._expandConvo(currentConvoLabeled, options, myContext || context, convoStepIndex + 1, currentStepsStack);
7219
+ }.bind(this);
7108
7220
 
7109
- this._expandConvo(expandedConvos, currentConvoLabeled, convoStepIndex + 1, currentStepsStack, myContext || context);
7110
- };
7111
-
7112
- if (this.caps[Capabilities.SCRIPTING_UTTEXPANSION_MODE] === 'index') {
7221
+ if (allutterances.length === 1) {
7222
+ yield* processSampleUtterances([allutterances[0]], context);
7223
+ } else if (this.caps[Capabilities.SCRIPTING_UTTEXPANSION_MODE] === 'index') {
7113
7224
  if (lodash.isNil(context.indexExpansionModeWidth)) {
7114
7225
  // executed for the first found utterance
7115
- processSampleUtterances(allutterances, Object.assign({}, context, {
7226
+ yield* processSampleUtterances(allutterances, Object.assign({}, context, {
7116
7227
  indexExpansionModeWidth: allutterances.length
7117
7228
  }));
7118
7229
  } else {
@@ -7130,7 +7241,7 @@ var ScriptingProvider_1 = class ScriptingProvider {
7130
7241
  const myContext = Object.assign({}, context, {
7131
7242
  indexExpansionModeWidth: Math.max(allutterances.length, context.indexExpansionModeWidth)
7132
7243
  });
7133
- processSampleUtterance(allutterances[localIndex], allutterances.length, localIndex, myContext);
7244
+ yield* processSampleUtterance(allutterances[localIndex], allutterances.length, localIndex, myContext);
7134
7245
 
7135
7246
  if (allutterances.length > context.indexExpansionModeWidth && context.indexExpansionModeIndex + 1 === context.indexExpansionModeWidth) {
7136
7247
  debug$9(`While expanding convos by index found in utterance "${uttName}" more examples (${allutterances.length}) as expected (${context.indexExpansionModeWidth})`);
@@ -7141,20 +7252,20 @@ var ScriptingProvider_1 = class ScriptingProvider {
7141
7252
  indexExpansionModeWidth: allutterances.length,
7142
7253
  indexExpansionModeIndex: i
7143
7254
  });
7144
- processSampleUtterance(allutterances[i], allutterances.length, i, myContext);
7255
+ yield* processSampleUtterance(allutterances[i], allutterances.length, i, myContext);
7145
7256
  }
7146
7257
  }
7147
7258
  }
7148
7259
  } else {
7149
7260
  if (this.caps[Capabilities.SCRIPTING_UTTEXPANSION_MODE] === 'first') {
7150
- processSampleUtterances([allutterances[0]]);
7261
+ yield* processSampleUtterances([allutterances[0]], context);
7151
7262
  } else if (this.caps[Capabilities.SCRIPTING_UTTEXPANSION_MODE] === 'random') {
7152
- processSampleUtterances(allutterances.map(x => ({
7263
+ yield* processSampleUtterances(allutterances.map(x => ({
7153
7264
  x,
7154
7265
  r: Math.random()
7155
- })).sort((a, b) => a.r - b.r).map(a => a.x).slice(0, this.caps[Capabilities.SCRIPTING_UTTEXPANSION_RANDOM_COUNT]));
7266
+ })).sort((a, b) => a.r - b.r).map(a => a.x).slice(0, this.caps[Capabilities.SCRIPTING_UTTEXPANSION_RANDOM_COUNT]), context);
7156
7267
  } else {
7157
- processSampleUtterances(allutterances);
7268
+ yield* processSampleUtterances(allutterances, context);
7158
7269
  }
7159
7270
  }
7160
7271
 
@@ -7163,7 +7274,8 @@ var ScriptingProvider_1 = class ScriptingProvider {
7163
7274
  }
7164
7275
 
7165
7276
  if (currentStep.userInputs && currentStep.userInputs.length > 0) {
7166
- currentStep.userInputs.forEach((ui, uiIndex) => {
7277
+ for (let uiIndex = 0; uiIndex < currentStep.userInputs.length; uiIndex++) {
7278
+ const ui = currentStep.userInputs[uiIndex];
7167
7279
  const userInput = this.userInputs[ui.name];
7168
7280
 
7169
7281
  if (userInput && userInput.expandConvo) {
@@ -7175,16 +7287,15 @@ var ScriptingProvider_1 = class ScriptingProvider {
7175
7287
 
7176
7288
  if (expandedUserInputs && expandedUserInputs.length > 0) {
7177
7289
  // let sampleinputs = expandedUserInputs
7178
- const processSampleInputs = (sampleinputs, myContext, uiIndex) => {
7179
- sampleinputs.forEach((input, index) => {
7180
- processSampleInput(input, sampleinputs.length, index, Object.assign({
7290
+ const processSampleInputs = function* (sampleinputs, myContext, uiIndex) {
7291
+ for (let index = 0; index < sampleinputs.length; index++) {
7292
+ yield* processSampleInput(sampleinputs[index], sampleinputs.length, index, Object.assign({
7181
7293
  indexExpansionModeIndex: index
7182
7294
  }, myContext || context), uiIndex);
7183
- });
7295
+ }
7184
7296
  };
7185
7297
 
7186
- const processSampleInput = (sampleinput, length, index, myContext, uiIndex) => {
7187
- const lineTag = `${index + 1}`.padStart(`${length}`.length, '0');
7298
+ const processSampleInput = function* (sampleinput, length, index, myContext, uiIndex) {
7188
7299
  const currentStepsStack = convoStepsStack.slice();
7189
7300
 
7190
7301
  const currentStepMod = lodash.cloneDeep(currentStep);
@@ -7194,16 +7305,27 @@ var ScriptingProvider_1 = class ScriptingProvider {
7194
7305
 
7195
7306
  const currentConvoLabeled = lodash.cloneDeep(currentConvo);
7196
7307
 
7197
- Object.assign(currentConvoLabeled.header, {
7198
- name: `${currentConvo.header.name}/${ui.name}-${utterancePostfix(lineTag, sampleinput.args && sampleinput.args.length ? sampleinput.args.join(', ') : 'no-args')}`
7199
- });
7308
+ if (length > 1) {
7309
+ if (sampleinput.convoPostfix) {
7310
+ Object.assign(currentConvoLabeled.header, {
7311
+ name: `${currentConvo.header.name}/${ui.name}-${sampleinput.convoPostfix}`
7312
+ });
7313
+ } else {
7314
+ const lineTag = `${index + 1}`.padStart(`${length}`.length, '0');
7315
+ Object.assign(currentConvoLabeled.header, {
7316
+ name: `${currentConvo.header.name}/${ui.name}-${utterancePostfix(lineTag, sampleinput.args && sampleinput.args.length ? sampleinput.args.join(', ') : 'no-args')}`
7317
+ });
7318
+ }
7319
+ }
7200
7320
 
7201
- this._expandConvo(expandedConvos, currentConvoLabeled, convoStepIndex + 1, currentStepsStack, myContext || context);
7202
- };
7321
+ yield* this._expandConvo(currentConvoLabeled, options, myContext || context, convoStepIndex + 1, currentStepsStack);
7322
+ }.bind(this);
7203
7323
 
7204
- if (this.caps[Capabilities.SCRIPTING_UTTEXPANSION_MODE] === 'index') {
7324
+ if (expandedUserInputs.length === 1) {
7325
+ yield* processSampleInputs([expandedUserInputs[0]], context, uiIndex);
7326
+ } else if (this.caps[Capabilities.SCRIPTING_UTTEXPANSION_MODE] === 'index') {
7205
7327
  if (lodash.isNil(context.indexExpansionModeWidth)) {
7206
- processSampleInputs(expandedUserInputs, Object.assign({}, context, {
7328
+ yield* processSampleInputs(expandedUserInputs, Object.assign({}, context, {
7207
7329
  indexExpansionModeWidth: expandedUserInputs.length
7208
7330
  }), uiIndex);
7209
7331
  } else {
@@ -7221,7 +7343,7 @@ var ScriptingProvider_1 = class ScriptingProvider {
7221
7343
  const myContext = Object.assign({}, context, {
7222
7344
  indexExpansionModeWidth: Math.max(expandedUserInputs.length, context.indexExpansionModeWidth)
7223
7345
  });
7224
- processSampleInput(expandedUserInputs[localIndex], expandedUserInputs.length, localIndex, myContext, uiIndex);
7346
+ yield* processSampleInput(expandedUserInputs[localIndex], expandedUserInputs.length, localIndex, myContext, uiIndex);
7225
7347
 
7226
7348
  if (expandedUserInputs.length > context.indexExpansionModeWidth && context.indexExpansionModeIndex + 1 === context.indexExpansionModeWidth) {
7227
7349
  debug$9(`While expanding convos by index found user input "${ui.name}, ${ui.args}" more examples (${expandedUserInputs.length}) as expected (${context.indexExpansionModeWidth})`);
@@ -7231,55 +7353,72 @@ var ScriptingProvider_1 = class ScriptingProvider {
7231
7353
  indexExpansionModeWidth: expandedUserInputs.length,
7232
7354
  indexExpansionModeIndex: i
7233
7355
  });
7234
- processSampleInput(expandedUserInputs[i], expandedUserInputs.length, i, myContext, uiIndex);
7356
+ yield* processSampleInput(expandedUserInputs[i], expandedUserInputs.length, i, myContext, uiIndex);
7235
7357
  }
7236
7358
  }
7237
7359
  }
7238
7360
  } else {
7239
7361
  if (this.caps[Capabilities.SCRIPTING_UTTEXPANSION_MODE] === 'first') {
7240
- processSampleInputs([expandedUserInputs[0]], context, uiIndex);
7362
+ yield* processSampleInputs([expandedUserInputs[0]], context, uiIndex);
7241
7363
  } else if (this.caps[Capabilities.SCRIPTING_UTTEXPANSION_MODE] === 'random') {
7242
- processSampleInputs(expandedUserInputs.map(x => ({
7364
+ yield* processSampleInputs(expandedUserInputs.map(x => ({
7243
7365
  x,
7244
7366
  r: Math.random()
7245
7367
  })).sort((a, b) => a.r - b.r).map(a => a.x).slice(0, this.caps[Capabilities.SCRIPTING_UTTEXPANSION_RANDOM_COUNT]), context, uiIndex);
7246
7368
  } else {
7247
- processSampleInputs(expandedUserInputs, context, uiIndex);
7369
+ yield* processSampleInputs(expandedUserInputs, context, uiIndex);
7248
7370
  }
7249
7371
  }
7250
7372
 
7251
7373
  useUnexpanded = false;
7252
7374
  }
7253
7375
  }
7254
- });
7376
+ }
7255
7377
  }
7256
7378
 
7257
7379
  if (useUnexpanded) {
7258
7380
  const currentStepsStack = convoStepsStack.slice();
7259
7381
  currentStepsStack.push(lodash.cloneDeep(currentStep));
7260
-
7261
- this._expandConvo(expandedConvos, currentConvo, convoStepIndex + 1, currentStepsStack, context);
7382
+ yield* this._expandConvo(currentConvo, options, context, convoStepIndex + 1, currentStepsStack);
7262
7383
  }
7263
7384
  }
7264
7385
  } else {
7265
- expandedConvos.push(Object.assign(lodash.cloneDeep(currentConvo), {
7386
+ const expanded = Object.assign(lodash.cloneDeep(currentConvo), {
7266
7387
  conversation: lodash.cloneDeep(convoStepsStack)
7267
- }));
7388
+ });
7389
+
7390
+ if (!options.convoFilter || options.convoFilter(expanded)) {
7391
+ context.count++;
7392
+ const logPerEntry = context.count < 10 ? 1 : context.count < 100 ? 10 : context.count < 1000 ? 100 : context.count < 10000 ? 1000 : 10000;
7393
+
7394
+ if (context.count % logPerEntry === 0) {
7395
+ debug$9(`Convo #${context.count} expanded (${expanded.header.name})`);
7396
+ }
7397
+
7398
+ yield expanded;
7399
+ }
7268
7400
  }
7269
7401
  }
7270
7402
 
7271
7403
  _sortConvos() {
7272
7404
  this.convos = lodash.sortBy(this.convos, [convo => convo.header.sort || convo.header.name]);
7405
+
7406
+ this._updateConvos();
7407
+ }
7408
+
7409
+ _updateConvos() {
7273
7410
  let i = 0;
7274
7411
  this.convos.forEach(convo => {
7275
- convo.header.order = ++i;
7412
+ if (convo) {
7413
+ convo.header.order = ++i;
7276
7414
 
7277
- if (!convo.header.projectname) {
7278
- convo.header.projectname = this.caps[Capabilities.PROJECTNAME];
7279
- }
7415
+ if (!convo.header.projectname) {
7416
+ convo.header.projectname = this.caps[Capabilities.PROJECTNAME];
7417
+ }
7280
7418
 
7281
- if (!convo.header.testsessionname) {
7282
- convo.header.testsessionname = this.caps[Capabilities.TESTSESSIONNAME];
7419
+ if (!convo.header.testsessionname) {
7420
+ convo.header.testsessionname = this.caps[Capabilities.TESTSESSIONNAME];
7421
+ }
7283
7422
  }
7284
7423
  });
7285
7424
  }
@@ -7291,7 +7430,11 @@ var ScriptingProvider_1 = class ScriptingProvider {
7291
7430
  this.convos.push(convos);
7292
7431
  }
7293
7432
 
7294
- this._sortConvos();
7433
+ if (this.convos.filter(c => lodash.isNil(c))) {
7434
+ this._updateConvos();
7435
+ } else {
7436
+ this._sortConvos();
7437
+ }
7295
7438
  }
7296
7439
 
7297
7440
  AddUtterances(utterances) {
@@ -7567,6 +7710,37 @@ var ScriptingProvider_1 = class ScriptingProvider {
7567
7710
  return ['digraph {', ...nodes, ...lines, '}'].join('\r\n');
7568
7711
  }
7569
7712
 
7713
+ GetAssertionCount(convo) {
7714
+ if (!convo) {
7715
+ return 0;
7716
+ }
7717
+
7718
+ let counter = 0;
7719
+
7720
+ for (const step of convo.conversation) {
7721
+ if (step.sender === 'bot') {
7722
+ let stepCounter = step.asserters ? step.asserters.length : 0;
7723
+
7724
+ if (step.messageText) {
7725
+ stepCounter++;
7726
+ }
7727
+
7728
+ stepCounter = stepCounter === 0 ? 1 : stepCounter;
7729
+ counter += stepCounter;
7730
+ }
7731
+ }
7732
+
7733
+ if (convo.convoBegin && convo.convoBegin.asserters) {
7734
+ counter += convo.convoBegin.asserters.length;
7735
+ }
7736
+
7737
+ if (convo.convoEnd && convo.convoEnd.asserters) {
7738
+ counter += convo.convoEnd.asserters.length;
7739
+ }
7740
+
7741
+ return counter === 0 ? 1 : counter;
7742
+ }
7743
+
7570
7744
  };
7571
7745
 
7572
7746
  var BaseRepo_1 = class BaseRepo {