botbuilder-dialogs-adaptive
Version:
Rule system for the Microsoft BotBuilder dialog system.
163 lines • 7.81 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.RegexRecognizer = void 0;
/**
* @module botbuilder-dialogs-adaptive
*/
/**
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
const recognizers_text_suite_1 = require("@microsoft/recognizers-text-suite");
const intentPattern_1 = require("./intentPattern");
const entityRecognizers_1 = require("./entityRecognizers");
const adaptiveRecognizer_1 = require("./adaptiveRecognizer");
const telemetryLoggerConstants_1 = require("../telemetryLoggerConstants");
class IntentPatternsConverter {
convert(items) {
const results = [];
items.forEach((item) => {
results.push(item instanceof intentPattern_1.IntentPattern ? item : new intentPattern_1.IntentPattern(item.intent, item.pattern));
});
return results;
}
}
/**
* Recognizer implementation which uses regex expressions to identify intents.
*/
class RegexRecognizer extends adaptiveRecognizer_1.AdaptiveRecognizer {
constructor() {
super(...arguments);
/**
* Array of patterns -> intent names.
*/
this.intents = [];
/**
* The entity recognizers.
*/
this.entities = [];
}
/**
* @param property The key of the conditional selector configuration.
* @returns The converter for the selector configuration.
*/
getConverter(property) {
switch (property) {
case 'intents':
return new IntentPatternsConverter();
default:
return super.getConverter(property);
}
}
/**
* Runs current DialogContext.TurnContext.Activity through a recognizer and returns a [RecognizerResult](xref:botbuilder-core.RecognizerResult).
*
* @param dialogContext The [DialogContext](xref:botbuilder-dialogs.DialogContext) for the current turn of conversation.
* @param activity [Activity](xref:botframework-schema.Activity) to recognize.
* @param telemetryProperties Optional, additional properties to be logged to telemetry with the LuisResult event.
* @param telemetryMetrics Optional, additional metrics to be logged to telemetry with the LuisResult event.
* @returns {Promise<RecognizerResult>} Analysis of utterance.
*/
recognize(dialogContext, activity, telemetryProperties, telemetryMetrics) {
var _a, _b, _c;
var _d, _e;
return __awaiter(this, void 0, void 0, function* () {
const text = (_a = activity.text) !== null && _a !== void 0 ? _a : '';
const locale = (_b = activity.locale) !== null && _b !== void 0 ? _b : recognizers_text_suite_1.Culture.English;
const recognizerResult = {
text: text,
intents: {},
entities: {},
};
if (!text) {
// nothing to recognize, return empty result
return recognizerResult;
}
const textEntity = new entityRecognizers_1.TextEntity(text);
textEntity.start = 0;
textEntity.end = text.length;
textEntity.score = 1.0;
const entityPool = [textEntity];
for (const intentPattern of this.intents) {
const matches = [];
let matched;
const regexp = intentPattern.regex;
while ((matched = regexp.exec(text))) {
matches.push(matched);
if (regexp.lastIndex == text.length || !regexp.lastIndex) {
break; // to avoid infinite loop
}
}
if (matches.length === 0) {
continue;
}
// TODO length weighted match and multiple intents
const intentKey = intentPattern.intent.split(' ').join('_');
(_c = (_d = recognizerResult.intents)[_e = `${intentKey}`]) !== null && _c !== void 0 ? _c : (_d[_e] = {
score: 1.0,
pattern: intentPattern.pattern,
});
matches.forEach((match) => {
if (match.groups) {
Object.entries(match.groups)
.filter(([_name, text]) => text !== undefined)
.forEach(([name, text]) => {
const entity = {
type: name,
text,
start: match.index,
end: match.index + text.length,
};
entityPool.push(entity);
});
}
});
}
if (this.entities) {
const entitySet = new entityRecognizers_1.EntityRecognizerSet(...this.entities);
const newEntities = yield entitySet.recognizeEntities(dialogContext, text, locale, entityPool);
entityPool.push(...newEntities);
}
entityPool
.filter((e) => e !== textEntity)
.forEach((entityResult) => {
var _a, _b, _c;
var _d, _e, _f, _g;
const { type: entityType, text: entityText } = entityResult;
(_a = (_d = recognizerResult.entities)[_e = `${entityType}`]) !== null && _a !== void 0 ? _a : (_d[_e] = []);
recognizerResult.entities[`${entityType}`].push(entityText);
(_b = (_f = recognizerResult.entities)['$instance']) !== null && _b !== void 0 ? _b : (_f['$instance'] = {});
const instanceRoot = recognizerResult.entities['$instance'];
(_c = instanceRoot[_g = `${entityType}`]) !== null && _c !== void 0 ? _c : (instanceRoot[_g] = []);
const instanceData = instanceRoot[`${entityType}`];
const instance = {
startIndex: entityResult.start,
endIndex: entityResult.end,
score: 1.0,
text: entityText,
type: entityType,
resolution: entityResult.resolution,
};
instanceData.push(instance);
});
if (Object.entries(recognizerResult.intents).length == 0) {
recognizerResult.intents.None = { score: 1.0 };
}
yield dialogContext.context.sendTraceActivity('RegexRecognizer', recognizerResult, 'RecognizerResult', 'Regex RecognizerResult');
this.trackRecognizerResult(dialogContext, telemetryLoggerConstants_1.TelemetryLoggerConstants.RegexRecognizerResultEvent, this.fillRecognizerResultTelemetryProperties(recognizerResult, telemetryProperties, dialogContext), telemetryMetrics);
return recognizerResult;
});
}
}
exports.RegexRecognizer = RegexRecognizer;
RegexRecognizer.$kind = 'Microsoft.RegexRecognizer';
//# sourceMappingURL=regexRecognizer.js.map