UNPKG

4.16 kBJavaScriptView Raw
1const request = require('request');
2
3class RasaAccessor {
4 constructor(RASA_URL, RASA_CONFIDENCE_THRESHOLD) {
5 this.RASA_URL = RASA_URL;
6 this.RASA_CONFIDENCE_THRESHOLD = RASA_CONFIDENCE_THRESHOLD;
7 }
8
9 resolveText(data, needsEntityConfident = true) {
10 return new Promise(resolve => {
11 const executor = async () => {
12 const { text } = data;
13 let { companyId } = data;
14 companyId = this.parseCompanyId(companyId);
15 const url = this.RASA_URL + '/parse';
16 try {
17 const result = await this.requestData(url, { q: text, project: companyId });
18 const response = JSON.parse(result.body);
19
20 const passConfidence = needsEntityConfident
21 ? response.intent.confidence >= this.RASA_CONFIDENCE_THRESHOLD &&
22 this.hasEntityConfident(response.entities, this.RASA_CONFIDENCE_THRESHOLD)
23 : response.intent.confidence >= this.RASA_CONFIDENCE_THRESHOLD ||
24 this.hasEntityConfident(response.entities, this.RASA_CONFIDENCE_THRESHOLD);
25
26 if (passConfidence) {
27 const intentBot = data.intents.find(item => {
28 return item.intent == response.intent.name;
29 });
30
31 if (intentBot) {
32 resolve(intentBot);
33 } else if (!needsEntityConfident) {
34 const entity = this.getEntityConfident(
35 response.entities,
36 this.RASA_CONFIDENCE_THRESHOLD,
37 );
38 const resolvedEntityText = await this.resolveText(
39 Object.assign(data, { text: entity.value }),
40 true,
41 );
42
43 resolve(resolvedEntityText);
44 }
45 }
46 } catch (e) {
47 // console.log('Erro no Rasa ', e);
48 }
49 // this.removeLoadedModels(companyId).catch(()=>{});
50 resolve(data.findIntent);
51 };
52
53 executor();
54 });
55 }
56
57 parseCompanyId(name) {
58 let companyId = name;
59 if (companyId.indexOf('.') > -1) {
60 const splited = companyId.split('.');
61 companyId = splited[splited.length - 1];
62 }
63 return companyId;
64 }
65
66 requestData(url, qs) {
67 return new Promise((resolve, reject) => {
68 request.get(url, { qs }, (err, res) => {
69 if (err) {
70 reject(err);
71 }
72 resolve(res);
73 });
74 });
75 }
76
77 hasEntityConfident(entities, threshold) {
78 for (const entity of entities) {
79 if (
80 entity.value === entity.entity ||
81 (entity.confidence &&
82 entity.confidence >= threshold &&
83 entity.processors &&
84 entity.processors.indexOf('ner_synonyms') > -1)
85 ) {
86 // entry is entity or synonym
87
88 return true;
89 }
90 }
91 return false;
92 }
93
94 getEntityConfident(entities, threshold) {
95 for (const entity of entities) {
96 if (entity.value === entity.entity || (entity.confidence && entity.confidence >= threshold)) {
97 // entry is entity or synonym
98 return entity;
99 }
100 }
101 }
102
103 removeLoadedModels(companyId) {
104 const statusUrl = `${this.RASA_URL}/status`;
105
106 return new Promise((resolve, reject) => {
107 request.get(statusUrl, (err, res) => {
108 if (!err) {
109 try {
110 const status = JSON.parse(res.body);
111 const availableProjects = status.available_projects;
112 const project = availableProjects[companyId];
113 const loadedModels = project.loaded_models;
114 if (loadedModels.length) {
115 for (const model of loadedModels) {
116 this.deleteModel(companyId, model).catch(() => {}); // Waiting is not necessary
117 }
118 }
119 resolve();
120 return;
121 } catch (e) {}
122 }
123
124 reject(err);
125 });
126 });
127 }
128
129 deleteModel(companyId, model) {
130 const deleteUrl = `${this.RASA_URL}/models`;
131 return new Promise((resolve, reject) => {
132 request.delete(deleteUrl, { qs: { project: companyId, model: model } }, (err, res) => {
133 if (!err) {
134 resolve(res);
135 return;
136 }
137 reject(err);
138 });
139 });
140 }
141}
142
143module.exports = RasaAccessor;