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
@@ -81,7 +81,7 @@ var express__default = /*#__PURE__*/_interopDefaultLegacy(express);
81
81
  var bodyParser__default = /*#__PURE__*/_interopDefaultLegacy(bodyParser);
82
82
 
83
83
  var name = "botium-core";
84
- var version$1 = "1.13.4";
84
+ var version$1 = "1.13.6";
85
85
  var description = "The Selenium for Chatbots";
86
86
  var main = "index.js";
87
87
  var module$1 = "dist/botium-es.js";
@@ -113,7 +113,7 @@ var bugs = {
113
113
  };
114
114
  var homepage = "https://www.botium.ai";
115
115
  var dependencies = {
116
- "@babel/runtime": "^7.18.6",
116
+ "@babel/runtime": "^7.19.0",
117
117
  async: "^3.2.4",
118
118
  "body-parser": "^1.20.0",
119
119
  boolean: "^3.2.0",
@@ -123,7 +123,7 @@ var dependencies = {
123
123
  esprima: "^4.0.1",
124
124
  express: "^4.18.1",
125
125
  globby: "11.0.4",
126
- ioredis: "^5.1.0",
126
+ ioredis: "^5.2.3",
127
127
  "is-class": "^0.0.9",
128
128
  "is-json": "^2.0.1",
129
129
  jsonpath: "^1.1.1",
@@ -140,13 +140,13 @@ var dependencies = {
140
140
  rimraf: "^3.0.2",
141
141
  "sanitize-filename": "^1.6.3",
142
142
  slugify: "^1.6.5",
143
- "socket.io": "^4.5.1",
144
- "socket.io-client": "^4.5.1",
143
+ "socket.io": "^4.5.2",
144
+ "socket.io-client": "^4.5.2",
145
145
  "socketio-auth": "^0.1.1",
146
- "swagger-jsdoc": "^6.2.1",
147
- "swagger-ui-express": "^4.4.0",
148
- uuid: "^8.3.2",
149
- vm2: "^3.9.10",
146
+ "swagger-jsdoc": "^6.2.5",
147
+ "swagger-ui-express": "^4.5.0",
148
+ uuid: "^9.0.0",
149
+ vm2: "^3.9.11",
150
150
  "word-error-rate": "0.0.7",
151
151
  "write-yaml": "^1.0.0",
152
152
  xlsx: "^0.18.5",
@@ -154,27 +154,27 @@ var dependencies = {
154
154
  yaml: "^2.1.1"
155
155
  };
156
156
  var devDependencies = {
157
- "@babel/core": "^7.18.6",
158
- "@babel/node": "^7.18.6",
159
- "@babel/plugin-transform-runtime": "^7.18.6",
160
- "@babel/preset-env": "^7.18.6",
157
+ "@babel/core": "^7.19.3",
158
+ "@babel/node": "^7.19.1",
159
+ "@babel/plugin-transform-runtime": "^7.19.1",
160
+ "@babel/preset-env": "^7.19.3",
161
161
  chai: "^4.3.6",
162
162
  "chai-as-promised": "^7.1.1",
163
163
  "cross-env": "^7.0.3",
164
- eslint: "^8.19.0",
164
+ eslint: "^8.24.0",
165
165
  "eslint-config-standard": "^17.0.0",
166
166
  "eslint-plugin-import": "^2.26.0",
167
167
  "eslint-plugin-mocha": "^10.1.0",
168
- "eslint-plugin-n": "^15.2.4",
169
- "eslint-plugin-promise": "^6.0.0",
168
+ "eslint-plugin-n": "^15.3.0",
169
+ "eslint-plugin-promise": "^6.0.1",
170
170
  "eslint-plugin-standard": "^4.1.0",
171
171
  "license-checker": "^25.0.1",
172
172
  "license-compatibility-checker": "^0.3.5",
173
173
  mocha: "^10.0.0",
174
- nock: "^13.2.8",
175
- "npm-check-updates": "^15.2.6",
174
+ nock: "^13.2.9",
175
+ "npm-check-updates": "^16.3.4",
176
176
  nyc: "^15.1.0",
177
- rollup: "^2.76.0",
177
+ rollup: "^2.79.1",
178
178
  "rollup-plugin-babel": "^4.4.0",
179
179
  "rollup-plugin-commonjs": "^10.1.0",
180
180
  "rollup-plugin-json": "^4.0.0",
@@ -2315,6 +2315,8 @@ const convoStepToLines$2 = step => {
2315
2315
  lines.push('MEDIA ' + step.media[0].mediaUri);
2316
2316
  } else if (step.messageText) {
2317
2317
  lines.push(step.messageText);
2318
+ } else if (step.sourceData) {
2319
+ lines.push(JSON.stringify(step.sourceData, null, 2));
2318
2320
  }
2319
2321
 
2320
2322
  step.userInputs && step.userInputs.forEach(userInput => {
@@ -2507,6 +2509,34 @@ const SCRIPTING_FUNCTIONS_RAW = {
2507
2509
  $timestamp: () => {
2508
2510
  return Date.now();
2509
2511
  },
2512
+ $tomorrow: pattern => {
2513
+ if (pattern) {
2514
+ return moment__default["default"]().add(1, 'day').format(pattern);
2515
+ }
2516
+
2517
+ return moment__default["default"]().add(1, 'day').toDate().toLocaleDateString();
2518
+ },
2519
+ $yesterday: pattern => {
2520
+ if (pattern) {
2521
+ return moment__default["default"]().subtract(1, 'day').format(pattern);
2522
+ }
2523
+
2524
+ return moment__default["default"]().subtract(1, 'day').toDate().toLocaleDateString();
2525
+ },
2526
+ $date_add: (amount, unit, pattern) => {
2527
+ if (pattern) {
2528
+ return moment__default["default"]().add(amount, unit).format(pattern);
2529
+ }
2530
+
2531
+ return moment__default["default"]().add(amount, unit).toDate().toLocaleDateString();
2532
+ },
2533
+ $date_subtract: (amount, unit, pattern) => {
2534
+ if (pattern) {
2535
+ return moment__default["default"]().subtract(amount, unit).format(pattern);
2536
+ }
2537
+
2538
+ return moment__default["default"]().subtract(amount, unit).toDate().toLocaleDateString();
2539
+ },
2510
2540
  $year: () => {
2511
2541
  return new Date().getFullYear();
2512
2542
  },
@@ -2598,7 +2628,8 @@ const SCRIPTING_FUNCTIONS_RAW = {
2598
2628
  require: false,
2599
2629
  env: caps[Capabilities.SECURITY_ALLOW_UNSAFE] ? process.env : {},
2600
2630
  sandbox: {
2601
- caps
2631
+ caps,
2632
+ moment: moment__default["default"]
2602
2633
  }
2603
2634
  });
2604
2635
  return vm.run(`module.exports = (${code})`);
@@ -2676,7 +2707,22 @@ const _apply = (scriptingMemory, str, caps, mockMsg) => {
2676
2707
  for (const match of matches) {
2677
2708
  if (match.indexOf('(') > 0) {
2678
2709
  const arg = match.substring(match.indexOf('(') + 1, match.lastIndexOf(')')).replace(/\\\)/g, ')');
2679
- str = str.replace(match, SCRIPTING_FUNCTIONS$1[key].handler(caps, arg, mockMsg));
2710
+ let args = [arg];
2711
+
2712
+ if (SCRIPTING_FUNCTIONS$1[key].numberOfArguments > 1) {
2713
+ args = arg.split(',');
2714
+ }
2715
+
2716
+ args = args.map(arg => {
2717
+ arg = arg.trim();
2718
+
2719
+ if (arg.startsWith('"') && arg.endsWith('"')) {
2720
+ return arg.substring(1, arg.length - 1);
2721
+ } else {
2722
+ return arg;
2723
+ }
2724
+ });
2725
+ str = str.replace(match, SCRIPTING_FUNCTIONS$1[key].handler(caps, ...args, mockMsg));
2680
2726
  } else {
2681
2727
  str = str.replace(match, SCRIPTING_FUNCTIONS$1[key].handler(caps));
2682
2728
  }
@@ -2787,7 +2833,10 @@ var RetryHelper_1 = class RetryHelper {
2787
2833
  factor: caps[`RETRY_${section.toUpperCase()}_FACTOR`] || (lodash__default["default"].isNil(options.factor) ? 1 : options.factor),
2788
2834
  minTimeout: caps[`RETRY_${section.toUpperCase()}_MINTIMEOUT`] || (lodash__default["default"].isNil(options.minTimeout) ? 1000 : options.minTimeout)
2789
2835
  };
2790
- 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()))}`);
2836
+
2837
+ if (this.retrySettings.retries > 0) {
2838
+ debug$j(`Retry for ${section} is enabled. Settings: ${JSON.stringify(this.retrySettings)} Patterns: ${JSON.stringify(this.retryErrorPatterns.map(r => r.toString()))}`);
2839
+ }
2791
2840
  }
2792
2841
 
2793
2842
  shouldRetry(err) {
@@ -3825,7 +3874,8 @@ const equals = ignoreCase => (botresponse, utterance) => {
3825
3874
  const wer = () => (botresponse, utterance, args) => {
3826
3875
  botresponse = _normalize(botresponse || '');
3827
3876
  utterance = toString(utterance || '');
3828
- return wordErrorRate__default["default"].wordErrorRate(botresponse, utterance) <= args[0];
3877
+ const threshold = [',', '.'].find(p => `${args[0]}`.includes(p)) ? parseFloat(args[0]) : parseInt(args[0]) / 100;
3878
+ return wordErrorRate__default["default"].wordErrorRate(botresponse, utterance) <= threshold;
3829
3879
  };
3830
3880
 
3831
3881
  const getMatchFunction$1 = matchingMode => {
@@ -4875,7 +4925,8 @@ var CompilerXlsx_1 = class CompilerXlsx extends CompilerBase_1 {
4875
4925
  convoResults.forEach(convo => {
4876
4926
  if (!convo.header.name) {
4877
4927
  convo.header.name = `${convo.header.sheetname}-${this.colnames[convo.header.colindex]}${formatRowIndex(convo.header.rowindex)}`;
4878
- }
4928
+ } // it is not used anymore?
4929
+
4879
4930
 
4880
4931
  convo.header.sort = convo.header.name;
4881
4932
  scriptResults.push(convo);
@@ -6219,7 +6270,7 @@ var ScriptingProvider_1 = class ScriptingProvider {
6219
6270
 
6220
6271
  const found = lodash__default["default"].find(tomatch, utt => this.matchFn(botresponse, utt, this.caps[Capabilities.SCRIPTING_MATCHING_MODE_ARGS]));
6221
6272
 
6222
- const asserterType = this.caps[Capabilities.SCRIPTING_MATCHING_MODE] === 'wer' ? 'WerAsserter' : 'TextMatchAsserter';
6273
+ const asserterType = this.caps[Capabilities.SCRIPTING_MATCHING_MODE] === 'wer' ? 'Word Error Rate Asserter' : 'Text Match Asserter';
6223
6274
 
6224
6275
  if (lodash__default["default"].isNil(found)) {
6225
6276
  let message = `${stepTag}: Bot response `;
@@ -6231,13 +6282,18 @@ var ScriptingProvider_1 = class ScriptingProvider {
6231
6282
  throw new BotiumError$2(message, {
6232
6283
  type: 'asserter',
6233
6284
  source: asserterType,
6285
+ params: {
6286
+ matchingMode: this.caps[Capabilities.SCRIPTING_MATCHING_MODE],
6287
+ args: this.caps[Capabilities.SCRIPTING_MATCHING_MODE_ARGS] || null
6288
+ },
6234
6289
  context: {
6235
6290
  stepTag
6236
6291
  },
6237
6292
  cause: {
6238
6293
  expected: tomatch,
6239
6294
  actual: botresponse,
6240
- matchingMode: this.caps[Capabilities.SCRIPTING_MATCHING_MODE]
6295
+ matchingMode: this.caps[Capabilities.SCRIPTING_MATCHING_MODE],
6296
+ args: this.caps[Capabilities.SCRIPTING_MATCHING_MODE_ARGS] || null
6241
6297
  }
6242
6298
  });
6243
6299
  }
@@ -6251,7 +6307,7 @@ var ScriptingProvider_1 = class ScriptingProvider {
6251
6307
 
6252
6308
  const found = lodash__default["default"].find(nottomatch, utt => this.matchFn(botresponse, utt, this.caps[Capabilities.SCRIPTING_MATCHING_MODE_ARGS]));
6253
6309
 
6254
- const asserterType = this.caps[Capabilities.SCRIPTING_MATCHING_MODE] === 'wer' ? 'WerAsserter' : 'TextMatchAsserter';
6310
+ const asserterType = this.caps[Capabilities.SCRIPTING_MATCHING_MODE] === 'wer' ? 'Word Error Rate Asserter' : 'Text Match Asserter';
6255
6311
 
6256
6312
  if (!lodash__default["default"].isNil(found)) {
6257
6313
  let message = `${stepTag}: Bot response `;
@@ -6263,6 +6319,10 @@ var ScriptingProvider_1 = class ScriptingProvider {
6263
6319
  throw new BotiumError$2(message, {
6264
6320
  type: 'asserter',
6265
6321
  source: asserterType,
6322
+ params: {
6323
+ matchingMode: this.caps[Capabilities.SCRIPTING_MATCHING_MODE],
6324
+ args: this.caps[Capabilities.SCRIPTING_MATCHING_MODE_ARGS] || null
6325
+ },
6266
6326
  context: {
6267
6327
  stepTag
6268
6328
  },
@@ -6270,7 +6330,8 @@ var ScriptingProvider_1 = class ScriptingProvider {
6270
6330
  not: true,
6271
6331
  expected: nottomatch,
6272
6332
  actual: botresponse,
6273
- matchingMode: this.caps[Capabilities.SCRIPTING_MATCHING_MODE]
6333
+ matchingMode: this.caps[Capabilities.SCRIPTING_MATCHING_MODE],
6334
+ args: this.caps[Capabilities.SCRIPTING_MATCHING_MODE_ARGS] || null
6274
6335
  }
6275
6336
  });
6276
6337
  }
@@ -7050,30 +7111,77 @@ var ScriptingProvider_1 = class ScriptingProvider {
7050
7111
  this._sortConvos();
7051
7112
  }
7052
7113
 
7053
- ExpandConvos() {
7114
+ ExpandConvos(options = {}) {
7115
+ options = Object.assign({
7116
+ // use skip and keep, or justHeader
7117
+ justHeader: false,
7118
+ // drop unwanted convos
7119
+ convoFilter: null
7120
+ }, options);
7121
+ const context = {
7122
+ count: 0
7123
+ };
7054
7124
  const expandedConvos = [];
7055
7125
  debug$9(`ExpandConvos - Using utterances expansion mode: ${this.caps[Capabilities.SCRIPTING_UTTEXPANSION_MODE]}`);
7056
7126
  this.convos.forEach(convo => {
7057
7127
  convo.expandPartialConvos();
7058
7128
 
7059
- this._expandConvo(expandedConvos, convo);
7129
+ for (const expanded of this._expandConvo(convo, options, context)) {
7130
+ expanded.header.assertionCount = this.GetAssertionCount(expanded);
7131
+
7132
+ if (options.justHeader) {
7133
+ const ConvoWithOnlyHeader = {
7134
+ header: {
7135
+ name: expanded.header.name,
7136
+ assertionCount: expanded.header.assertionCount
7137
+ }
7138
+ };
7139
+ expandedConvos.push(ConvoWithOnlyHeader);
7140
+ } else {
7141
+ expandedConvos.push(expanded);
7142
+ }
7143
+ }
7060
7144
  });
7061
7145
  this.convos = expandedConvos;
7062
7146
 
7063
- this._sortConvos();
7147
+ if (!options.justHeader) {
7148
+ this._sortConvos();
7149
+ } else {
7150
+ this._updateConvos();
7151
+ }
7152
+ }
7153
+
7154
+ ExpandConvosIterable(options = {}) {
7155
+ options = Object.assign({
7156
+ // drop unwanted convos
7157
+ convoFilter: null
7158
+ }, options);
7159
+ debug$9(`ExpandConvos - Using utterances expansion mode: ${this.caps[Capabilities.SCRIPTING_UTTEXPANSION_MODE]}`); // creating a nested generator, calling the other.
7160
+ // We hope this.convos does not changes while this iterator is used
7161
+
7162
+ const _convosIterable = function* (options) {
7163
+ const context = {
7164
+ count: 0
7165
+ };
7166
+
7167
+ for (const convo of this.convos) {
7168
+ convo.expandPartialConvos();
7169
+ yield* this._expandConvo(convo, options, context);
7170
+ }
7171
+ }.bind(this);
7172
+
7173
+ this.convosIterable = _convosIterable(options);
7064
7174
  }
7065
7175
  /**
7066
- *
7067
- * @param expandedConvos
7176
+ * This is a generator function with yield
7068
7177
  * @param currentConvo
7069
7178
  * @param convoStepIndex
7070
7179
  * @param convoStepsStack list of ConvoSteps
7071
- * @param context {width: }
7072
7180
  * @private
7073
7181
  */
7074
7182
 
7075
7183
 
7076
- _expandConvo(expandedConvos, currentConvo, convoStepIndex = 0, convoStepsStack = [], context = {}) {
7184
+ *_expandConvo(currentConvo, options, context, convoStepIndex = 0, convoStepsStack = []) {
7077
7185
  const utterancePostfix = (lineTag, uttOrUserInput) => {
7078
7186
  const naming = this.caps[Capabilities.SCRIPTING_UTTEXPANSION_NAMING_MODE] || Defaults$1.capabilities[Capabilities.SCRIPTING_UTTEXPANSION_NAMING_MODE];
7079
7187
 
@@ -7099,8 +7207,7 @@ var ScriptingProvider_1 = class ScriptingProvider {
7099
7207
  if (currentStep.sender === 'bot' || currentStep.sender === 'begin' || currentStep.sender === 'end') {
7100
7208
  const currentStepsStack = convoStepsStack.slice();
7101
7209
  currentStepsStack.push(lodash__default["default"].cloneDeep(currentStep));
7102
-
7103
- this._expandConvo(expandedConvos, currentConvo, convoStepIndex + 1, currentStepsStack, context);
7210
+ yield* this._expandConvo(currentConvo, options, context, convoStepIndex + 1, currentStepsStack);
7104
7211
  } else if (currentStep.sender === 'me') {
7105
7212
  let useUnexpanded = true;
7106
7213
 
@@ -7122,16 +7229,15 @@ var ScriptingProvider_1 = class ScriptingProvider {
7122
7229
  if (this.utterances[uttName]) {
7123
7230
  const allutterances = this.utterances[uttName].utterances;
7124
7231
 
7125
- const processSampleUtterances = (sampleutterances, myContext) => {
7126
- sampleutterances.forEach((utt, index) => {
7127
- processSampleUtterance(utt, sampleutterances.length, index, Object.assign({
7232
+ const processSampleUtterances = function* (sampleutterances, myContext) {
7233
+ for (let index = 0; index < sampleutterances.length; index++) {
7234
+ yield* processSampleUtterance(sampleutterances[index], sampleutterances.length, index, Object.assign({
7128
7235
  indexExpansionModeIndex: index
7129
7236
  }, myContext || context));
7130
- });
7237
+ }
7131
7238
  };
7132
7239
 
7133
- const processSampleUtterance = (sampleutterance, length, index, myContext) => {
7134
- const lineTag = `${index + 1}`.padStart(`${length}`.length, '0');
7240
+ const processSampleUtterance = function* (sampleutterance, length, index, myContext) {
7135
7241
  const currentStepsStack = convoStepsStack.slice();
7136
7242
 
7137
7243
  if (uttArgs) {
@@ -7144,19 +7250,24 @@ var ScriptingProvider_1 = class ScriptingProvider {
7144
7250
 
7145
7251
  const currentConvoLabeled = lodash__default["default"].cloneDeep(currentConvo);
7146
7252
 
7147
- Object.assign(currentConvoLabeled.header, {
7148
- name: `${currentConvo.header.name}/${uttName}-${utterancePostfix(lineTag, sampleutterance)}`
7149
- });
7253
+ if (length > 1) {
7254
+ const lineTag = `${index + 1}`.padStart(`${length}`.length, '0');
7255
+ Object.assign(currentConvoLabeled.header, {
7256
+ name: `${currentConvo.header.name}/${uttName}-${utterancePostfix(lineTag, sampleutterance)}`
7257
+ });
7258
+ }
7259
+
7150
7260
  if (!currentConvoLabeled.sourceTag) currentConvoLabeled.sourceTag = {};
7151
7261
  if (!currentConvoLabeled.sourceTag.origConvoName) currentConvoLabeled.sourceTag.origConvoName = currentConvo.header.name;
7262
+ yield* this._expandConvo(currentConvoLabeled, options, myContext || context, convoStepIndex + 1, currentStepsStack);
7263
+ }.bind(this);
7152
7264
 
7153
- this._expandConvo(expandedConvos, currentConvoLabeled, convoStepIndex + 1, currentStepsStack, myContext || context);
7154
- };
7155
-
7156
- if (this.caps[Capabilities.SCRIPTING_UTTEXPANSION_MODE] === 'index') {
7265
+ if (allutterances.length === 1) {
7266
+ yield* processSampleUtterances([allutterances[0]], context);
7267
+ } else if (this.caps[Capabilities.SCRIPTING_UTTEXPANSION_MODE] === 'index') {
7157
7268
  if (lodash__default["default"].isNil(context.indexExpansionModeWidth)) {
7158
7269
  // executed for the first found utterance
7159
- processSampleUtterances(allutterances, Object.assign({}, context, {
7270
+ yield* processSampleUtterances(allutterances, Object.assign({}, context, {
7160
7271
  indexExpansionModeWidth: allutterances.length
7161
7272
  }));
7162
7273
  } else {
@@ -7174,7 +7285,7 @@ var ScriptingProvider_1 = class ScriptingProvider {
7174
7285
  const myContext = Object.assign({}, context, {
7175
7286
  indexExpansionModeWidth: Math.max(allutterances.length, context.indexExpansionModeWidth)
7176
7287
  });
7177
- processSampleUtterance(allutterances[localIndex], allutterances.length, localIndex, myContext);
7288
+ yield* processSampleUtterance(allutterances[localIndex], allutterances.length, localIndex, myContext);
7178
7289
 
7179
7290
  if (allutterances.length > context.indexExpansionModeWidth && context.indexExpansionModeIndex + 1 === context.indexExpansionModeWidth) {
7180
7291
  debug$9(`While expanding convos by index found in utterance "${uttName}" more examples (${allutterances.length}) as expected (${context.indexExpansionModeWidth})`);
@@ -7185,20 +7296,20 @@ var ScriptingProvider_1 = class ScriptingProvider {
7185
7296
  indexExpansionModeWidth: allutterances.length,
7186
7297
  indexExpansionModeIndex: i
7187
7298
  });
7188
- processSampleUtterance(allutterances[i], allutterances.length, i, myContext);
7299
+ yield* processSampleUtterance(allutterances[i], allutterances.length, i, myContext);
7189
7300
  }
7190
7301
  }
7191
7302
  }
7192
7303
  } else {
7193
7304
  if (this.caps[Capabilities.SCRIPTING_UTTEXPANSION_MODE] === 'first') {
7194
- processSampleUtterances([allutterances[0]]);
7305
+ yield* processSampleUtterances([allutterances[0]], context);
7195
7306
  } else if (this.caps[Capabilities.SCRIPTING_UTTEXPANSION_MODE] === 'random') {
7196
- processSampleUtterances(allutterances.map(x => ({
7307
+ yield* processSampleUtterances(allutterances.map(x => ({
7197
7308
  x,
7198
7309
  r: Math.random()
7199
- })).sort((a, b) => a.r - b.r).map(a => a.x).slice(0, this.caps[Capabilities.SCRIPTING_UTTEXPANSION_RANDOM_COUNT]));
7310
+ })).sort((a, b) => a.r - b.r).map(a => a.x).slice(0, this.caps[Capabilities.SCRIPTING_UTTEXPANSION_RANDOM_COUNT]), context);
7200
7311
  } else {
7201
- processSampleUtterances(allutterances);
7312
+ yield* processSampleUtterances(allutterances, context);
7202
7313
  }
7203
7314
  }
7204
7315
 
@@ -7207,7 +7318,8 @@ var ScriptingProvider_1 = class ScriptingProvider {
7207
7318
  }
7208
7319
 
7209
7320
  if (currentStep.userInputs && currentStep.userInputs.length > 0) {
7210
- currentStep.userInputs.forEach((ui, uiIndex) => {
7321
+ for (let uiIndex = 0; uiIndex < currentStep.userInputs.length; uiIndex++) {
7322
+ const ui = currentStep.userInputs[uiIndex];
7211
7323
  const userInput = this.userInputs[ui.name];
7212
7324
 
7213
7325
  if (userInput && userInput.expandConvo) {
@@ -7219,16 +7331,15 @@ var ScriptingProvider_1 = class ScriptingProvider {
7219
7331
 
7220
7332
  if (expandedUserInputs && expandedUserInputs.length > 0) {
7221
7333
  // let sampleinputs = expandedUserInputs
7222
- const processSampleInputs = (sampleinputs, myContext, uiIndex) => {
7223
- sampleinputs.forEach((input, index) => {
7224
- processSampleInput(input, sampleinputs.length, index, Object.assign({
7334
+ const processSampleInputs = function* (sampleinputs, myContext, uiIndex) {
7335
+ for (let index = 0; index < sampleinputs.length; index++) {
7336
+ yield* processSampleInput(sampleinputs[index], sampleinputs.length, index, Object.assign({
7225
7337
  indexExpansionModeIndex: index
7226
7338
  }, myContext || context), uiIndex);
7227
- });
7339
+ }
7228
7340
  };
7229
7341
 
7230
- const processSampleInput = (sampleinput, length, index, myContext, uiIndex) => {
7231
- const lineTag = `${index + 1}`.padStart(`${length}`.length, '0');
7342
+ const processSampleInput = function* (sampleinput, length, index, myContext, uiIndex) {
7232
7343
  const currentStepsStack = convoStepsStack.slice();
7233
7344
 
7234
7345
  const currentStepMod = lodash__default["default"].cloneDeep(currentStep);
@@ -7238,16 +7349,27 @@ var ScriptingProvider_1 = class ScriptingProvider {
7238
7349
 
7239
7350
  const currentConvoLabeled = lodash__default["default"].cloneDeep(currentConvo);
7240
7351
 
7241
- Object.assign(currentConvoLabeled.header, {
7242
- name: `${currentConvo.header.name}/${ui.name}-${utterancePostfix(lineTag, sampleinput.args && sampleinput.args.length ? sampleinput.args.join(', ') : 'no-args')}`
7243
- });
7352
+ if (length > 1) {
7353
+ if (sampleinput.convoPostfix) {
7354
+ Object.assign(currentConvoLabeled.header, {
7355
+ name: `${currentConvo.header.name}/${ui.name}-${sampleinput.convoPostfix}`
7356
+ });
7357
+ } else {
7358
+ const lineTag = `${index + 1}`.padStart(`${length}`.length, '0');
7359
+ Object.assign(currentConvoLabeled.header, {
7360
+ name: `${currentConvo.header.name}/${ui.name}-${utterancePostfix(lineTag, sampleinput.args && sampleinput.args.length ? sampleinput.args.join(', ') : 'no-args')}`
7361
+ });
7362
+ }
7363
+ }
7244
7364
 
7245
- this._expandConvo(expandedConvos, currentConvoLabeled, convoStepIndex + 1, currentStepsStack, myContext || context);
7246
- };
7365
+ yield* this._expandConvo(currentConvoLabeled, options, myContext || context, convoStepIndex + 1, currentStepsStack);
7366
+ }.bind(this);
7247
7367
 
7248
- if (this.caps[Capabilities.SCRIPTING_UTTEXPANSION_MODE] === 'index') {
7368
+ if (expandedUserInputs.length === 1) {
7369
+ yield* processSampleInputs([expandedUserInputs[0]], context, uiIndex);
7370
+ } else if (this.caps[Capabilities.SCRIPTING_UTTEXPANSION_MODE] === 'index') {
7249
7371
  if (lodash__default["default"].isNil(context.indexExpansionModeWidth)) {
7250
- processSampleInputs(expandedUserInputs, Object.assign({}, context, {
7372
+ yield* processSampleInputs(expandedUserInputs, Object.assign({}, context, {
7251
7373
  indexExpansionModeWidth: expandedUserInputs.length
7252
7374
  }), uiIndex);
7253
7375
  } else {
@@ -7265,7 +7387,7 @@ var ScriptingProvider_1 = class ScriptingProvider {
7265
7387
  const myContext = Object.assign({}, context, {
7266
7388
  indexExpansionModeWidth: Math.max(expandedUserInputs.length, context.indexExpansionModeWidth)
7267
7389
  });
7268
- processSampleInput(expandedUserInputs[localIndex], expandedUserInputs.length, localIndex, myContext, uiIndex);
7390
+ yield* processSampleInput(expandedUserInputs[localIndex], expandedUserInputs.length, localIndex, myContext, uiIndex);
7269
7391
 
7270
7392
  if (expandedUserInputs.length > context.indexExpansionModeWidth && context.indexExpansionModeIndex + 1 === context.indexExpansionModeWidth) {
7271
7393
  debug$9(`While expanding convos by index found user input "${ui.name}, ${ui.args}" more examples (${expandedUserInputs.length}) as expected (${context.indexExpansionModeWidth})`);
@@ -7275,55 +7397,72 @@ var ScriptingProvider_1 = class ScriptingProvider {
7275
7397
  indexExpansionModeWidth: expandedUserInputs.length,
7276
7398
  indexExpansionModeIndex: i
7277
7399
  });
7278
- processSampleInput(expandedUserInputs[i], expandedUserInputs.length, i, myContext, uiIndex);
7400
+ yield* processSampleInput(expandedUserInputs[i], expandedUserInputs.length, i, myContext, uiIndex);
7279
7401
  }
7280
7402
  }
7281
7403
  }
7282
7404
  } else {
7283
7405
  if (this.caps[Capabilities.SCRIPTING_UTTEXPANSION_MODE] === 'first') {
7284
- processSampleInputs([expandedUserInputs[0]], context, uiIndex);
7406
+ yield* processSampleInputs([expandedUserInputs[0]], context, uiIndex);
7285
7407
  } else if (this.caps[Capabilities.SCRIPTING_UTTEXPANSION_MODE] === 'random') {
7286
- processSampleInputs(expandedUserInputs.map(x => ({
7408
+ yield* processSampleInputs(expandedUserInputs.map(x => ({
7287
7409
  x,
7288
7410
  r: Math.random()
7289
7411
  })).sort((a, b) => a.r - b.r).map(a => a.x).slice(0, this.caps[Capabilities.SCRIPTING_UTTEXPANSION_RANDOM_COUNT]), context, uiIndex);
7290
7412
  } else {
7291
- processSampleInputs(expandedUserInputs, context, uiIndex);
7413
+ yield* processSampleInputs(expandedUserInputs, context, uiIndex);
7292
7414
  }
7293
7415
  }
7294
7416
 
7295
7417
  useUnexpanded = false;
7296
7418
  }
7297
7419
  }
7298
- });
7420
+ }
7299
7421
  }
7300
7422
 
7301
7423
  if (useUnexpanded) {
7302
7424
  const currentStepsStack = convoStepsStack.slice();
7303
7425
  currentStepsStack.push(lodash__default["default"].cloneDeep(currentStep));
7304
-
7305
- this._expandConvo(expandedConvos, currentConvo, convoStepIndex + 1, currentStepsStack, context);
7426
+ yield* this._expandConvo(currentConvo, options, context, convoStepIndex + 1, currentStepsStack);
7306
7427
  }
7307
7428
  }
7308
7429
  } else {
7309
- expandedConvos.push(Object.assign(lodash__default["default"].cloneDeep(currentConvo), {
7430
+ const expanded = Object.assign(lodash__default["default"].cloneDeep(currentConvo), {
7310
7431
  conversation: lodash__default["default"].cloneDeep(convoStepsStack)
7311
- }));
7432
+ });
7433
+
7434
+ if (!options.convoFilter || options.convoFilter(expanded)) {
7435
+ context.count++;
7436
+ const logPerEntry = context.count < 10 ? 1 : context.count < 100 ? 10 : context.count < 1000 ? 100 : context.count < 10000 ? 1000 : 10000;
7437
+
7438
+ if (context.count % logPerEntry === 0) {
7439
+ debug$9(`Convo #${context.count} expanded (${expanded.header.name})`);
7440
+ }
7441
+
7442
+ yield expanded;
7443
+ }
7312
7444
  }
7313
7445
  }
7314
7446
 
7315
7447
  _sortConvos() {
7316
7448
  this.convos = lodash__default["default"].sortBy(this.convos, [convo => convo.header.sort || convo.header.name]);
7449
+
7450
+ this._updateConvos();
7451
+ }
7452
+
7453
+ _updateConvos() {
7317
7454
  let i = 0;
7318
7455
  this.convos.forEach(convo => {
7319
- convo.header.order = ++i;
7456
+ if (convo) {
7457
+ convo.header.order = ++i;
7320
7458
 
7321
- if (!convo.header.projectname) {
7322
- convo.header.projectname = this.caps[Capabilities.PROJECTNAME];
7323
- }
7459
+ if (!convo.header.projectname) {
7460
+ convo.header.projectname = this.caps[Capabilities.PROJECTNAME];
7461
+ }
7324
7462
 
7325
- if (!convo.header.testsessionname) {
7326
- convo.header.testsessionname = this.caps[Capabilities.TESTSESSIONNAME];
7463
+ if (!convo.header.testsessionname) {
7464
+ convo.header.testsessionname = this.caps[Capabilities.TESTSESSIONNAME];
7465
+ }
7327
7466
  }
7328
7467
  });
7329
7468
  }
@@ -7335,7 +7474,11 @@ var ScriptingProvider_1 = class ScriptingProvider {
7335
7474
  this.convos.push(convos);
7336
7475
  }
7337
7476
 
7338
- this._sortConvos();
7477
+ if (this.convos.filter(c => lodash__default["default"].isNil(c))) {
7478
+ this._updateConvos();
7479
+ } else {
7480
+ this._sortConvos();
7481
+ }
7339
7482
  }
7340
7483
 
7341
7484
  AddUtterances(utterances) {
@@ -7611,6 +7754,37 @@ var ScriptingProvider_1 = class ScriptingProvider {
7611
7754
  return ['digraph {', ...nodes, ...lines, '}'].join('\r\n');
7612
7755
  }
7613
7756
 
7757
+ GetAssertionCount(convo) {
7758
+ if (!convo) {
7759
+ return 0;
7760
+ }
7761
+
7762
+ let counter = 0;
7763
+
7764
+ for (const step of convo.conversation) {
7765
+ if (step.sender === 'bot') {
7766
+ let stepCounter = step.asserters ? step.asserters.length : 0;
7767
+
7768
+ if (step.messageText) {
7769
+ stepCounter++;
7770
+ }
7771
+
7772
+ stepCounter = stepCounter === 0 ? 1 : stepCounter;
7773
+ counter += stepCounter;
7774
+ }
7775
+ }
7776
+
7777
+ if (convo.convoBegin && convo.convoBegin.asserters) {
7778
+ counter += convo.convoBegin.asserters.length;
7779
+ }
7780
+
7781
+ if (convo.convoEnd && convo.convoEnd.asserters) {
7782
+ counter += convo.convoEnd.asserters.length;
7783
+ }
7784
+
7785
+ return counter === 0 ? 1 : counter;
7786
+ }
7787
+
7614
7788
  };
7615
7789
 
7616
7790
  var BaseRepo_1 = class BaseRepo {