UNPKG

asksuite-core

Version:
150 lines (133 loc) 4.4 kB
const request = require('request'); const FallbackResolver = require('../util/FallbackResolver'); const RequestPreprocessor = require('../util/RequestPreprocessor'); const { ErrorHandlerService } = require('./ErrorHandlerService'); const URLRegex = /^[(http(s)?):\/\/(www\.)?a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)$/gi; class OpenAiAccessor { constructor(baseUrl, enabled, corePayload) { this.baseUrl = baseUrl; this.enabled = !!enabled; this.corePayload = corePayload; } resolveText(request) { console.log('[OpenAiAccessor.resolveText started]'); return new Promise((resolve) => { const defaultIntent = FallbackResolver.fallbackWithDefaultIntent(request.intents) || {}; if (!this.enabled) { console.warn('[OpenAiAccessor disabled]'); resolve(defaultIntent); return; } const executor = async () => { const cleanText = RequestPreprocessor.removeUtilityTexts( RequestPreprocessor.removeEmoji(request.text), ).trim(); const companyId = this.parseCompanyId(request.companyId); if (this.isNotUnderstandable(cleanText)) { defaultIntent.processingStep = { fallbackReason: 'text_not_understandable', intentFound: 'naoentendi', text: cleanText || '', }; resolve(defaultIntent); return; } try { const result = await this.requestData(this.baseUrl, { question: cleanText, companyId, language: request.language, conversationId: (this.corePayload || {}).conversationId, }); if (!result.body.choices) { throw { message: result.statusMessage, code: result.statusCode }; } const textResponse = result.body.choices[0].message.content; console.log('[OpenAiAccessor textResponse]', textResponse); if (this.textToKeyword(textResponse).endsWith('naoentendi')) { defaultIntent.processingStep = { fallbackReason: 'intent_not_found', intentFound: null, extraInfo: result.body.usage || null, text: cleanText || '', answer: textResponse || '', }; resolve(defaultIntent); return; } const generateDialog = this.generateDialog(companyId, textResponse); resolve({ ...generateDialog, processingStep: { fallbackReason: null, intentFound: generateDialog.intent, extraInfo: result.body.usage || null, text: cleanText || '', answer: textResponse || '', context: result.body.metadata, }, }); } catch (e) { console.error('[OpenAiAccessor error]', e); const errorData = ErrorHandlerService.accessorErrorHandler(e); defaultIntent.processingStep = { fallbackReason: 'intent_not_found', intentFound: null, errorData, }; resolve(defaultIntent); } }; executor().then(); }); } requestData(url, json) { return new Promise((resolve, reject) => { request.post(url, { json }, (err, res) => { if (err) { reject(err); } resolve(res); }); }); } parseCompanyId(name) { let companyId = name; if (companyId.indexOf('.') > -1) { const splited = companyId.split('.'); companyId = splited[splited.length - 1]; } return companyId; } generateDialog(companyId, text) { return { intent: 'openai', dialog: `${companyId}.openai`, value: this.clearResponse(text), type: 'text', goToDialog: `${companyId}.encerramento`, }; } clearResponse(text) { if (text.startsWith('Resposta:')) { return text.substr(10); } return text; } textToKeyword(text = '') { return text .toLowerCase() .normalize('NFD') .replace(/[^a-z]/g, ''); } isNotUnderstandable(cleanText) { return ( !cleanText || // empty string !/\w/gi.test(cleanText) || // Only special chars !/\D/gi.test(cleanText) || // Only digits URLRegex.test(cleanText) // Only link ); } } module.exports = OpenAiAccessor;