UNPKG

asksuite-core

Version:
232 lines (190 loc) 8.23 kB
const AWSLambdaCaller = require('./services/AWSLambdaCaller'); const Util = require('./util'); const MediaResolver = require('./util/MediaResolver'); const DialogFlowAccessor = require('./services/DialogFlowAccessor'); const QuoteDataAccessor = require('./services/QuoteDataAccessor'); const KeyMatcherAccessor = require('./services/KeyMatcherAccessor'); const RasaAccessor = require('./services/RasaAccessor'); const RasaLayersAccessor = require('./services/RasaLayersAccessor'); const RasaLayersRedisService = require('./services/RasaLayersRedisService'); const defaultFallbackIntent = require('./util/defaultFallbackIntent'); const RequestPreprocessor = require('./util/RequestPreprocessor'); const AsksuiteProcessingNaturalUtils = require('./AsksuiteProcessingNaturalUtils'); const NodeCache = require('node-cache'); const DEFAULT_LANGUAGE = 'pt-br'; const intentsNotFoundCache = new NodeCache({ stdTTL: 300, checkperiod: 120 }); class AsksuiteProcessingNatural { static get ORDERED_ACCESSORS() { return ['RASA_LAYERS', 'DIALOG_FLOW', 'RASA', 'KEY_MATCHER']; } // Robot will search for intents in this order default static get RASA_FIRST_ORDERED_ACCESSORS() { return ['RASA', 'RASA_LAYERS', 'DIALOG_FLOW', 'KEY_MATCHER']; } // Robot will search for intents in this order if tryRasaFirst option is set to true constructor(config) { this.config = config; this.utils = new AsksuiteProcessingNaturalUtils(this.config); this.rasaLayersRedisService = new RasaLayersRedisService({ config: config.config, redis: config.redis, }); } findIntent(request) { return new Promise((resolve, reject) => { const executor = async request => { let intent = { fromCache: false, }; request = await RequestPreprocessor.process(request); const awsLambdaCaller = new AWSLambdaCaller(request.config.CORE_LAMBDA_AWS); const dialogFlowAccessor = new DialogFlowAccessor(awsLambdaCaller); const keyMatcherAccessor = new KeyMatcherAccessor(awsLambdaCaller); const rasaAccessor = new RasaAccessor( request.config.RASA_URL, request.config.RASA_CONFIDENCE_THRESHOLD, ); const rasaLayersAccessor = new RasaLayersAccessor(awsLambdaCaller); let orderOption = AsksuiteProcessingNatural.ORDERED_ACCESSORS; if (request.tryRasaFirst) { orderOption = AsksuiteProcessingNatural.RASA_FIRST_ORDERED_ACCESSORS; } request.findIntent = defaultFallbackIntent(request.companyId); request.translated = false; request.translation = null; for (const accessorName of orderOption) { switch (accessorName) { case 'DIALOG_FLOW': intent = await this.utils.findIntentDialogFlow(dialogFlowAccessor, request, false); if ( Util.isNaoentendi(intent.intent) && this.utils.resolveLanguage(request.language, request.languages) !== DEFAULT_LANGUAGE ) { intent = await this.utils.findIntentDialogFlow(dialogFlowAccessor, request, true); } break; case 'KEY_MATCHER': intent = await keyMatcherAccessor.resolveText(request); if ( Util.isNaoentendi(intent.intent) && this.utils.resolveLanguage(request.language, request.languages) !== DEFAULT_LANGUAGE ) { const toSend = await this.utils.copyRequestToDefaultLanguage(request); intent = await keyMatcherAccessor.resolveText(toSend); } intent.keywordTry = { try: true }; break; case 'RASA': intent = await rasaAccessor.resolveText(request, request.needsRasaEntityConfident); break; case 'RASA_LAYERS': if (request.order && request.order.length) { let cached = null; try { cached = await this.rasaLayersRedisService.resolveText( request.text, request.language, request.order, request.languages, ); } catch (e) { console.error(e); } intent = cached ? cached : await rasaLayersAccessor.resolveText(request); } break; } request.findIntent = intent; if (intent.intent && !Util.isNaoentendi(intent.intent)) { intent.resolver = accessorName; if (intent.resolver === 'KEY_MATCHER') { intent.keywordTry.match = intent.intent; intent.keywordTry.intent = intent.intent; } else if (intent.resolver === 'RASA_LAYERS') { await this.rasaLayersRedisService .saveToCache( intent, request.text, request.language, intent.order, request.languages, ) .catch(console.error); } //FOR exit condition break; } } const language = this.utils.resolveLanguage(request.language, request.languages); const key = `${request.companyId}.${request.userId}.${language}`; if (Util.isNaoentendi(intent.intent)) { let count = intentsNotFoundCache.get(key) || 0; intentsNotFoundCache.set(key, ++count); const { ATTEMPTS_BEFORE_DETECTING_LANGUAGE, LANGUAGE_DETECTION_CONFIDENCE, } = request.config; if (count === ATTEMPTS_BEFORE_DETECTING_LANGUAGE) { const detection = await this.utils.detectLanguage(request); if (detection.confidence >= LANGUAGE_DETECTION_CONFIDENCE) { const languageCode = detection.isSupported ? detection.language.code : detection.fallbackLanguage; if (request.language.substring(0, 2) !== languageCode.substring(0, 2)) { intent.languageDetected = detection; intentsNotFoundCache.del(key); } } } if (count > 1 && !intent.languageDetected) { const fallbackIntent = defaultFallbackIntent(request.companyId, count); intent = this.utils.findDialogByIntent(request, fallbackIntent.intent); } } else { intentsNotFoundCache.del(key); } intent.translated = request.translated; intent.translation = request.translation; return intent; }; executor(request) .then(resolve) .catch(reject); }); } resolveMedia(request) { return new Promise((resolve, reject) => { try { const mediaResolver = new MediaResolver(request.companyId); mediaResolver .resolve(request.media, request.intents) .then(resolve) .catch(reject); } catch (e) { reject(e); } }); } async extractQuoteData(request) { request = await RequestPreprocessor.process(request); const awsLambdaCaller = new AWSLambdaCaller(request.config.CORE_LAMBDA_AWS); const quoteDataAccessor = new QuoteDataAccessor(awsLambdaCaller); return await quoteDataAccessor.resolveText(request); } async extractTextNumbers(request) { request = await RequestPreprocessor.process(request); const awsLambdaCaller = new AWSLambdaCaller(request.config.CORE_LAMBDA_AWS); const quoteDataAccessor = new QuoteDataAccessor(awsLambdaCaller); return await quoteDataAccessor.resolveTextNumbers(request); } async findRasaIntent(request) { let intent = {}; intent = defaultFallbackIntent(request.companyId); request.findIntent = intent; request = await this.utils.copyRequestToDefaultLanguage(request); const rasaAccessor = new RasaAccessor( request.config.RASA_URL, request.config.RASA_CONFIDENCE_THRESHOLD, ); return await rasaAccessor.resolveText(request, request.needsRasaEntityConfident); } } module.exports = AsksuiteProcessingNatural;