botium-core 1.14.9 → 1.14.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -4
- package/dist/botium-cjs.js +65 -20
- package/dist/botium-cjs.js.map +1 -1
- package/dist/botium-es.js +65 -20
- package/dist/botium-es.js.map +1 -1
- package/package.json +2 -1
- package/src/scripting/Convo.js +39 -3
- package/src/scripting/ScriptingProvider.js +18 -11
- package/src/scripting/logichook/LogicHookUtils.js +8 -10
- package/src/scripting/logichook/userinput/MediaInput.js +2 -2
- package/test/convo/transcript.spec.js +93 -1
- package/test/scripting/logichooks/localvsglobal.spec.js +105 -0
package/README.md
CHANGED
|
@@ -13,10 +13,6 @@
|
|
|
13
13
|
|
|
14
14
|
**_IF YOU LIKE WHAT YOU SEE, PLEASE CONSIDER GIVING US A STAR ON GITHUB!_**
|
|
15
15
|
|
|
16
|
-
**UPDATE 2020/11/05:** Botium has a FREE, hosted plan available! The new Botium Box Mini is our ❤️ to the community. [Take it for a test drive 🚗 ...](https://www.botium.ai/pricing/)
|
|
17
|
-
|
|
18
|
-
[](https://www.youtube.com/watch?v=ciVxojvRfng "Botium Box Mini")
|
|
19
|
-
|
|
20
16
|
## Getting Help
|
|
21
17
|
|
|
22
18
|
See our [Botium Forum](https://forum.botium.ai/)
|
package/dist/botium-cjs.js
CHANGED
|
@@ -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.
|
|
80
|
+
var version$1 = "1.14.10";
|
|
81
81
|
var description = "The Selenium for Chatbots";
|
|
82
82
|
var main = "index.js";
|
|
83
83
|
var module$1 = "dist/botium-es.js";
|
|
@@ -140,6 +140,7 @@ 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
|
+
tinyglobby: "^0.2.10",
|
|
143
144
|
uuid: "^9.0.1",
|
|
144
145
|
"word-error-rate": "0.0.7",
|
|
145
146
|
"write-yaml": "^1.0.0",
|
|
@@ -1124,9 +1125,9 @@ var LogicHookUtils_1 = class LogicHookUtils {
|
|
|
1124
1125
|
caps
|
|
1125
1126
|
}) {
|
|
1126
1127
|
this.asserters = {};
|
|
1127
|
-
this.
|
|
1128
|
+
this.globalAsserterNames = [];
|
|
1128
1129
|
this.logicHooks = {};
|
|
1129
|
-
this.
|
|
1130
|
+
this.globalLogicHookNames = [];
|
|
1130
1131
|
this.userInputs = {};
|
|
1131
1132
|
this.buildScriptContext = buildScriptContext;
|
|
1132
1133
|
this.caps = caps;
|
|
@@ -1159,7 +1160,7 @@ var LogicHookUtils_1 = class LogicHookUtils {
|
|
|
1159
1160
|
}
|
|
1160
1161
|
this.asserters[asserter.ref] = this._loadClass(asserter, 'asserter');
|
|
1161
1162
|
if (asserter.global) {
|
|
1162
|
-
this.
|
|
1163
|
+
this.globalAsserterNames.push(asserter.ref);
|
|
1163
1164
|
}
|
|
1164
1165
|
});
|
|
1165
1166
|
}
|
|
@@ -1170,7 +1171,7 @@ var LogicHookUtils_1 = class LogicHookUtils {
|
|
|
1170
1171
|
}
|
|
1171
1172
|
this.logicHooks[logicHook.ref] = this._loadClass(logicHook, 'logichook');
|
|
1172
1173
|
if (logicHook.global) {
|
|
1173
|
-
this.
|
|
1174
|
+
this.globalLogicHookNames.push(logicHook.ref);
|
|
1174
1175
|
}
|
|
1175
1176
|
});
|
|
1176
1177
|
}
|
|
@@ -1182,11 +1183,17 @@ var LogicHookUtils_1 = class LogicHookUtils {
|
|
|
1182
1183
|
this.userInputs[userInput.ref] = this._loadClass(userInput, 'userinput');
|
|
1183
1184
|
});
|
|
1184
1185
|
}
|
|
1185
|
-
|
|
1186
|
-
return this.
|
|
1186
|
+
getGlobalAsserters() {
|
|
1187
|
+
return this.globalAsserterNames.reduce((agg, name) => ({
|
|
1188
|
+
...agg,
|
|
1189
|
+
[name]: this.asserters[name]
|
|
1190
|
+
}), {});
|
|
1187
1191
|
}
|
|
1188
|
-
|
|
1189
|
-
return this.
|
|
1192
|
+
getGlobalLogicHooks() {
|
|
1193
|
+
return this.globalLogicHookNames.reduce((agg, name) => ({
|
|
1194
|
+
...agg,
|
|
1195
|
+
[name]: this.logicHooks[name]
|
|
1196
|
+
}), {});
|
|
1190
1197
|
}
|
|
1191
1198
|
_loadClass({
|
|
1192
1199
|
src,
|
|
@@ -2976,6 +2983,10 @@ class Convo$6 {
|
|
|
2976
2983
|
let skipTranscriptStep = false;
|
|
2977
2984
|
let conditionalGroupId = null;
|
|
2978
2985
|
let conditionMetInGroup = false;
|
|
2986
|
+
let skipOptionalStep = false;
|
|
2987
|
+
// If there are optional step(s) in the conversation, and the message from the bot fails on each optional bot step(s) and/or mandatory bot step, then we have an unexpected message.
|
|
2988
|
+
// So in this case an unexpected error should be shown instead of the latest assertion error.
|
|
2989
|
+
let optionalStepAssertionError = false;
|
|
2979
2990
|
let globalConvoStepParameters = container.caps[Capabilities.SCRIPTING_CONVO_STEP_PARAMETERS] || {};
|
|
2980
2991
|
let retryBotMessageTimeoutEnd = null;
|
|
2981
2992
|
let retryBotMessageConvoId = null;
|
|
@@ -2983,6 +2994,13 @@ class Convo$6 {
|
|
|
2983
2994
|
for (let i = 0; i < this.conversation.length; i = retryBotMessageDropBotResponse ? i : i + 1) {
|
|
2984
2995
|
retryBotMessageDropBotResponse = false;
|
|
2985
2996
|
const convoStep = this.conversation[i];
|
|
2997
|
+
if (!convoStep.optional) {
|
|
2998
|
+
skipOptionalStep = false;
|
|
2999
|
+
}
|
|
3000
|
+
if (convoStep.optional && skipOptionalStep) {
|
|
3001
|
+
// If there are multiple optional steps, and the previous optional step was timeout, then the next optional step should be skipped to prevent too long convo run with multiple timeout.
|
|
3002
|
+
continue;
|
|
3003
|
+
}
|
|
2986
3004
|
const rawConvoStepParameters = convoStep.logicHooks.find(lh => lh.name === 'CONVO_STEP_PARAMETERS')?.args;
|
|
2987
3005
|
let convoStepParameters = {};
|
|
2988
3006
|
if (rawConvoStepParameters && rawConvoStepParameters.length) {
|
|
@@ -3167,7 +3185,8 @@ class Convo$6 {
|
|
|
3167
3185
|
debug$k(`${this.header.name}: bot says (cleaned by binary and base64 data and sourceData) ${JSON.stringify(coreMsg, null, 2)}`);
|
|
3168
3186
|
} catch (err) {
|
|
3169
3187
|
transcriptStep.botEnd = new Date();
|
|
3170
|
-
if (convoStep.optional) {
|
|
3188
|
+
if (!(err.message.indexOf('Bot did not respond within') < 0) && convoStep.optional) {
|
|
3189
|
+
skipOptionalStep = true;
|
|
3171
3190
|
continue;
|
|
3172
3191
|
}
|
|
3173
3192
|
const failErr = botiumErrorFromErr$1(`${this.header.name}/${convoStep.stepTag}: error waiting for bot - ${err.message}`, err);
|
|
@@ -3251,6 +3270,7 @@ class Convo$6 {
|
|
|
3251
3270
|
}
|
|
3252
3271
|
waitForBotSays = false;
|
|
3253
3272
|
skipTranscriptStep = true;
|
|
3273
|
+
optionalStepAssertionError = true;
|
|
3254
3274
|
return true;
|
|
3255
3275
|
} else if (retryOn) {
|
|
3256
3276
|
if (!retryBotMessageTimeoutEnd || retryBotMessageConvoId !== convoStep.stepTag) {
|
|
@@ -3268,9 +3288,18 @@ class Convo$6 {
|
|
|
3268
3288
|
}
|
|
3269
3289
|
}
|
|
3270
3290
|
if (container.caps[Capabilities.SCRIPTING_ENABLE_MULTIPLE_ASSERT_ERRORS]) {
|
|
3271
|
-
|
|
3291
|
+
if (optionalStepAssertionError) {
|
|
3292
|
+
optionalStepAssertionError = false;
|
|
3293
|
+
assertErrors.push(new BotiumError$2(`${this.header.name}: Unexpected message.`));
|
|
3294
|
+
} else {
|
|
3295
|
+
assertErrors.push(err);
|
|
3296
|
+
}
|
|
3272
3297
|
return false;
|
|
3273
3298
|
} else {
|
|
3299
|
+
if (optionalStepAssertionError) {
|
|
3300
|
+
optionalStepAssertionError = false;
|
|
3301
|
+
throw new BotiumError$2(`${this.header.name}: Unexpected message.`);
|
|
3302
|
+
}
|
|
3274
3303
|
throw err;
|
|
3275
3304
|
}
|
|
3276
3305
|
};
|
|
@@ -3284,6 +3313,7 @@ class Convo$6 {
|
|
|
3284
3313
|
if (convoStep.not) {
|
|
3285
3314
|
try {
|
|
3286
3315
|
this.scriptingEvents.assertBotNotResponse(response, tomatch, `${this.header.name}/${convoStep.stepTag}`, lastMeConvoStep, convoStepParameters);
|
|
3316
|
+
optionalStepAssertionError = false;
|
|
3287
3317
|
} catch (err) {
|
|
3288
3318
|
if (isErrorHandledWithOptionConvoStep(err)) {
|
|
3289
3319
|
continue;
|
|
@@ -3292,6 +3322,7 @@ class Convo$6 {
|
|
|
3292
3322
|
} else {
|
|
3293
3323
|
try {
|
|
3294
3324
|
this.scriptingEvents.assertBotResponse(response, tomatch, `${this.header.name}/${convoStep.stepTag}`, lastMeConvoStep, convoStepParameters);
|
|
3325
|
+
optionalStepAssertionError = false;
|
|
3295
3326
|
} catch (err) {
|
|
3296
3327
|
if (isErrorHandledWithOptionConvoStep(err)) {
|
|
3297
3328
|
continue;
|
|
@@ -3301,6 +3332,7 @@ class Convo$6 {
|
|
|
3301
3332
|
} else if (convoStep.sourceData) {
|
|
3302
3333
|
try {
|
|
3303
3334
|
this._compareObject(container, scriptingMemory, convoStep, botMsg.sourceData, convoStep.sourceData, botMsg, convoStepParameters);
|
|
3335
|
+
optionalStepAssertionError = false;
|
|
3304
3336
|
} catch (err) {
|
|
3305
3337
|
if (isErrorHandledWithOptionConvoStep(err)) {
|
|
3306
3338
|
continue;
|
|
@@ -3327,11 +3359,13 @@ class Convo$6 {
|
|
|
3327
3359
|
transcript,
|
|
3328
3360
|
transcriptStep
|
|
3329
3361
|
});
|
|
3362
|
+
optionalStepAssertionError = false;
|
|
3330
3363
|
} catch (err) {
|
|
3331
3364
|
const nextConvoStep = this.conversation[i + 1];
|
|
3332
3365
|
if (convoStep.optional && nextConvoStep && nextConvoStep.sender === 'bot') {
|
|
3333
3366
|
waitForBotSays = false;
|
|
3334
3367
|
skipTranscriptStep = true;
|
|
3368
|
+
optionalStepAssertionError = true;
|
|
3335
3369
|
continue;
|
|
3336
3370
|
}
|
|
3337
3371
|
const errors = err.toArray ? err.toArray() : [];
|
|
@@ -3360,8 +3394,17 @@ class Convo$6 {
|
|
|
3360
3394
|
this.scriptingEvents.fail && this.scriptingEvents.fail(failErr, lastMeConvoStep);
|
|
3361
3395
|
} catch (failErr) {}
|
|
3362
3396
|
if (container.caps[Capabilities.SCRIPTING_ENABLE_MULTIPLE_ASSERT_ERRORS] && err instanceof BotiumError$2) {
|
|
3363
|
-
|
|
3397
|
+
if (optionalStepAssertionError) {
|
|
3398
|
+
optionalStepAssertionError = false;
|
|
3399
|
+
assertErrors.push(new BotiumError$2(`${this.header.name}: Unexpected message.`));
|
|
3400
|
+
} else {
|
|
3401
|
+
assertErrors.push(err);
|
|
3402
|
+
}
|
|
3364
3403
|
} else {
|
|
3404
|
+
if (optionalStepAssertionError) {
|
|
3405
|
+
optionalStepAssertionError = false;
|
|
3406
|
+
throw new BotiumError$2(`${this.header.name}: Unexpected message.`);
|
|
3407
|
+
}
|
|
3365
3408
|
throw failErr;
|
|
3366
3409
|
}
|
|
3367
3410
|
}
|
|
@@ -5562,9 +5605,9 @@ var ScriptingProvider_1 = class ScriptingProvider {
|
|
|
5562
5605
|
this.utterances = {};
|
|
5563
5606
|
this.matchFn = null;
|
|
5564
5607
|
this.asserters = {};
|
|
5565
|
-
this.
|
|
5608
|
+
this.globalAsserters = {};
|
|
5566
5609
|
this.logicHooks = {};
|
|
5567
|
-
this.
|
|
5610
|
+
this.globalLogicHooks = {};
|
|
5568
5611
|
this.userInputs = {};
|
|
5569
5612
|
this.partialConvos = {};
|
|
5570
5613
|
this.scriptingMemories = [];
|
|
@@ -5933,7 +5976,8 @@ var ScriptingProvider_1 = class ScriptingProvider {
|
|
|
5933
5976
|
return p(this.retryHelperAsserter, () => asserter[asserterType](params));
|
|
5934
5977
|
}
|
|
5935
5978
|
};
|
|
5936
|
-
const
|
|
5979
|
+
const localAsserters = (asserters || []).filter(a => this.asserters[a.name][asserterType]);
|
|
5980
|
+
const convoStepPromises = localAsserters.map(a => ({
|
|
5937
5981
|
asserter: a,
|
|
5938
5982
|
promise: callAsserter(a, this.asserters[a.name], {
|
|
5939
5983
|
convo,
|
|
@@ -5948,7 +5992,8 @@ var ScriptingProvider_1 = class ScriptingProvider {
|
|
|
5948
5992
|
promise,
|
|
5949
5993
|
asserter
|
|
5950
5994
|
}) => updateExceptionContext(promise, asserter));
|
|
5951
|
-
const
|
|
5995
|
+
const globalAsserters = Object.keys(this.globalAsserters).filter(name => localAsserters.map(a => a.name).indexOf(name) < 0).reduce((agg, name) => [...agg, this.globalAsserters[name]], []).filter(a => a[asserterType]);
|
|
5996
|
+
const globalPromises = globalAsserters.map(a => ({
|
|
5952
5997
|
asserter: a,
|
|
5953
5998
|
promise: p(this.retryHelperAsserter, () => a[asserterType]({
|
|
5954
5999
|
convo,
|
|
@@ -5963,7 +6008,7 @@ var ScriptingProvider_1 = class ScriptingProvider {
|
|
|
5963
6008
|
promise,
|
|
5964
6009
|
asserter
|
|
5965
6010
|
}) => updateExceptionContext(promise, asserter));
|
|
5966
|
-
const allPromises = [...
|
|
6011
|
+
const allPromises = [...convoStepPromises, ...globalPromises];
|
|
5967
6012
|
if (this.caps[Capabilities.SCRIPTING_ENABLE_MULTIPLE_ASSERT_ERRORS]) {
|
|
5968
6013
|
return Promise.allSettled(allPromises).then(results => {
|
|
5969
6014
|
const rejected = results.filter(result => result.status === 'rejected').map(result => result.reason);
|
|
@@ -5998,7 +6043,7 @@ var ScriptingProvider_1 = class ScriptingProvider {
|
|
|
5998
6043
|
isGlobal: false,
|
|
5999
6044
|
...rest
|
|
6000
6045
|
})));
|
|
6001
|
-
const globalHooks = Object.
|
|
6046
|
+
const globalHooks = Object.keys(this.globalLogicHooks).filter(name => localHooks.map(l => l.name).indexOf(name) < 0).reduce((agg, name) => [...agg, this.globalLogicHooks[name]], []).filter(l => l[hookType]);
|
|
6002
6047
|
const globalPromises = globalHooks.map(l => p(this.retryHelperLogicHook, () => l[hookType]({
|
|
6003
6048
|
convo,
|
|
6004
6049
|
convoStep,
|
|
@@ -6118,9 +6163,9 @@ var ScriptingProvider_1 = class ScriptingProvider {
|
|
|
6118
6163
|
caps: this.caps
|
|
6119
6164
|
});
|
|
6120
6165
|
this.asserters = logicHookUtils.asserters;
|
|
6121
|
-
this.
|
|
6166
|
+
this.globalAsserters = logicHookUtils.getGlobalAsserters();
|
|
6122
6167
|
this.logicHooks = logicHookUtils.logicHooks;
|
|
6123
|
-
this.
|
|
6168
|
+
this.globalLogicHooks = logicHookUtils.getGlobalLogicHooks();
|
|
6124
6169
|
this.userInputs = logicHookUtils.userInputs;
|
|
6125
6170
|
}
|
|
6126
6171
|
IsAsserterValid(name) {
|