UNPKG

recime-bot-runtime

Version:

This runtime is intended to run inside a micro-service container with platform specific integration and module interpreter.

253 lines (252 loc) 11.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var request = require("request"); var flattern = require("lodash.flatten"); var bot_model_1 = require("./../bot-model"); var not_supported_1 = require("./services/not-supported"); var luis_1 = require("./services/luis"); var wit_1 = require("./services/wit"); var rasa_1 = require("./services/rasa"); var DefaultBlock = 'default'; var ConfidenceThreshold = 0.8; var Nlp = /** @class */ (function () { function Nlp() { } Nlp.request = function (context) { var _this = this; var args = context.args; var body = this.processBody(args); return new Promise(function (resolve, reject) { return _this.getIntents(context).then(function (intents) { var model = new bot_model_1.BotModel(context.bot.id); if (body.event) { var normalizedEvent_1 = body.event.toLowerCase(); var intent_1 = intents.find(function (i) { return i.name.toLowerCase() === normalizedEvent_1; }); if (!intent_1 || !intent_1.response || !intent_1.response.length) { intent_1 = intents.find(function (i) { return i.name.toLowerCase() === DefaultBlock; }); } return model.logIntentHit(intent_1.title).then(function () { resolve({ response: intent_1.response }); }); } // const fuzzyMatched = FuzzyMatcher.findMatch(intents, body); // if (fuzzyMatched // && fuzzyMatched.response // && fuzzyMatched.response.length) { // console.log('fuzzy-response', fuzzyMatched.response); // return model.logIntentHit(fuzzyMatched.title).then(() => { // resolve({ // response: fuzzyMatched.response, // nlp : { // entities: [], // intent : { // name : fuzzyMatched.title, // confidence: 1 // } // } // }); // }); // } return _this.response(context, body).then(function (r) { var unmapped = void 0; if (r.intent === DefaultBlock) { unmapped = true; } var intent = intents.find(function (i) { return i.name.toLowerCase() === r.intent; }); var tasks = [model.logIntentHit(intent.title)]; if (unmapped && body.text) { tasks.push(model.logUnhandledMessage(body.text)); } return Promise.all(tasks).then(function () { return resolve({ response: intent && intent.response, nlp: r.response }); }); }).catch(function (error) { var intent = intents.find(function (i) { return i.name.toLowerCase() === DefaultBlock; }); return model.logIntentHit(intent.title).then(function () { return resolve({ response: intent.response }); }); }); }); }); }; Nlp.normalizeNlpResponse = function (context, nlp) { var meta = context.bot.meta.rasa; if (meta) { return { entities: (nlp.entities || []).map(function (e) { e.entity = meta.entities.find(function (entity) { return entity.name === e.entity; }).title || e.entity; return { confidence: e.confidence, entity: e.entity, value: e.value, start: e.start, end: e.end }; }), intent: { name: nlp.intent.name ? flattern(meta.groups.map(function (g) { return g.intents || []; })).find(function (i) { return i.name === nlp.intent.name; }).title : nlp.intent.name || DefaultBlock, confidence: nlp.intent.confidence } }; } return nlp; }; Nlp.response = function (context, body) { var _this = this; var provider = this.getProvider(context.bot); // process using NLP. return provider.process(body).then(function (result) { if (!result) { return result; } console.log('nlp-response:', result); var bestMatch; if (provider instanceof wit_1.Wit) { if (result.entities && result.entities.intent && result.entities.intent.length) { var filteredMatches = result.entities.intent .filter(function (x) { return x.confidence > ConfidenceThreshold; }) .sort(function (x, y) { if (x.confidence > y.confidence) { return 1; } if (x.confidence < y.confidence) { return -1; } return 0; }) .map(function (intent) { return intent.value; }); bestMatch = filteredMatches.length && filteredMatches[0]; } } else if (provider instanceof not_supported_1.NotSupported) { if (result.intents && result.intents.length) { var filteredMatches = result.intents .filter(function (x) { return x.confidence > ConfidenceThreshold; }) .sort(function (x, y) { if (x.confidence > y.confidence) { return 1; } if (x.confidence < y.confidence) { return -1; } return 0; }) .map(function (intent) { return intent.slug; }); bestMatch = filteredMatches.length && filteredMatches[0]; } } else if (provider instanceof luis_1.Luis) { bestMatch = result && result.topScoringIntent; if (bestMatch && (bestMatch.intent || '').toLowerCase() !== 'none' && bestMatch.score > ConfidenceThreshold) { bestMatch = bestMatch.intent; } else { bestMatch = void 0; } } else if (provider instanceof rasa_1.Rasa) { bestMatch = result && result.intent; if (bestMatch && bestMatch.confidence > ConfidenceThreshold) { bestMatch = bestMatch.name; } else { bestMatch = void 0; } } return { intent: bestMatch || DefaultBlock, response: _this.normalizeNlpResponse(context, result) }; }); }; Nlp.getProvider = function (bot) { switch (bot.config.SYSTEM_RECIME_NLP.toLowerCase()) { case 'wit': { return new wit_1.Wit(bot); } case 'luis': { return new luis_1.Luis(bot); } case 'rasa': { return new rasa_1.Rasa(bot); } } return new not_supported_1.NotSupported(bot); }; Nlp.getIntents = function (context) { var env = context.bot.config; return new Promise(function (resolve, reject) { request({ uri: 'https://nlp-api.recime.io/v1/graphql', method: 'POST', json: true, headers: { 'x-recime-api-key': env.SYSTEM_RECIME_API_KEY }, body: { query: "\n query intents($botId: ID!) {\n intents(botId: $botId) { \n id\n name\n title\n expressions {\n id\n text\n }\n response {\n id\n type\n content\n }\n }\n }", variables: { botId: context.bot.id } } }, function (error, response, body) { if (body.errors) { // eslint-disable-next-line no-console console.error('ERROR:', JSON.stringify(body.errors, void 0, 2)); return reject(new Error(body.errors[0].message)); } resolve(body.data['intents']); }); }); }; Nlp.processBody = function (args) { if (args.event && args.event.name) { return { event: args.event.name }; } var rawBody = args.rawBody || {}; if (process.env['SYSTEM_RECIME_NLP'] === 'wit') { if (rawBody.message && rawBody.message.nlp) { var confidenceThreshold_1 = 0.8; var nlp = rawBody.message.nlp; var bestMatch = void 0; if (nlp.entities && nlp.entities["intent"]) { bestMatch = nlp.entities.intent .filter(function (x) { return x.confidence > confidenceThreshold_1; }) .sort(function (x, y) { if (x.confidence > y.confidence) { return 1; } if (x.confidence < y.confidence) { return -1; } return 0; }) .map(function (intent) { return intent.value; }); console.log('wit', bestMatch); return { event: bestMatch.length ? bestMatch[0] : DefaultBlock }; } if (!bestMatch) { return { event: DefaultBlock }; } } } return { text: args.text }; }; return Nlp; }()); exports.Nlp = Nlp;