Dialog being called again.

This commit is contained in:
Rodrigo Rodriguez 2018-08-28 19:16:29 -03:00
parent 3118b45543
commit 9bd5995115
4 changed files with 146 additions and 142 deletions

View file

@ -79,7 +79,7 @@ export class GBConversationalService implements IGBConversationalService {
// Resolve intents returned from LUIS // Resolve intents returned from LUIS
let topIntent = LuisRecognizer.topIntent(res); let topIntent = LuisRecognizer.topIntent(res);
if (topIntent) { if (topIntent) {
var intent = topIntent; var intent = topIntent;
var entity = var entity =
res.entities && res.entities.length > 0 res.entities && res.entities.length > 0

View file

@ -33,6 +33,7 @@
"use strict"; "use strict";
const gBuilder = require("botbuilder"); const gBuilder = require("botbuilder");
const {TextPrompt} = require("botbuilder-dialogs");
const UrlJoin = require("url-join"); const UrlJoin = require("url-join");
const Path = require("path"); const Path = require("path");
const Fs = require("fs"); const Fs = require("fs");
@ -192,7 +193,6 @@ export class GBMinService {
min.core = _this_.core; min.core = _this_.core;
min.conversationalService = _this_.conversationalService; min.conversationalService = _this_.conversationalService;
_this_.core.loadInstance(min.botId, (data, err) => { _this_.core.loadInstance(min.botId, (data, err) => {
min.instance = data; min.instance = data;
@ -229,6 +229,10 @@ export class GBMinService {
logger.trace( logger.trace(
`GeneralBots(${instance.engineName}) listening on: ${url}.` `GeneralBots(${instance.engineName}) listening on: ${url}.`
); );
min.dialogs.add('textPrompt', new TextPrompt());
server.post(`/api/messages/${instance.botId}`, (req, res) => { server.post(`/api/messages/${instance.botId}`, (req, res) => {
@ -248,7 +252,7 @@ export class GBMinService {
user.loaded = true; user.loaded = true;
user.subjects = []; user.subjects = [];
} }
if (context.activity.type === "conversationUpdate" && if (context.activity.type === "conversationUpdate" &&
context.activity.membersAdded.length > 0) { context.activity.membersAdded.length > 0) {
@ -439,7 +443,7 @@ export class GBMinService {
} else if (Path.extname(filename) === ".gbtheme") { } else if (Path.extname(filename) === ".gbtheme") {
server.use("/themes/" + filenameOnly, express.static(filename)); server.use("/themes/" + filenameOnly, express.static(filename));
logger.trace(`Theme (.gbtheme) assets acessible at: ${"/themes/" + filenameOnly}.`); logger.trace(`Theme (.gbtheme) assets accessible at: ${"/themes/" + filenameOnly}.`);
/** Knowledge base for bots. */ /** Knowledge base for bots. */

View file

@ -92,109 +92,103 @@ export class AskDialog extends IGBDialog {
// Searches KB for the first time. // Searches KB for the first time.
service.ask( let resultsA = await service.ask(
min.instance, min.instance,
text, text,
min.instance.searchScore, min.instance.searchScore,
user.subjects, user.subjects);
async resultsA => {
// Stops any content on projector. // Stops any content on projector.
min.conversationalService.sendEvent(dc, "stop", null);
min.conversationalService.sendEvent(dc, "stop", null); // If there is some result, answer immediately.
// If there is some result, answer immediately. if (resultsA && resultsA.answer) {
if (resultsA && resultsA.answer) { // Saves some context info.
// Saves some context info. user.isAsking = false;
user.lastQuestionId = resultsA.questionId;
user.isAsking = false; // Sends the answer to all outputs, including projector.
user.lastQuestionId = resultsA.questionId;
// Sends the answer to all outputs, including projector. service.sendAnswer(min.conversationalService,
dc,
resultsA.answer
);
service.sendAnswer(min.conversationalService, // Goes to ask loop, again.
dc,
resultsA.answer
);
// Goes to ask loop, again. dc.replace("/ask", { isReturning: true });
dc.replace("/ask", { isReturning: true }); } else {
} else { // Second time running Search, now with no filter.
// Second time running Search, now with no filter. let resultsB = await service.ask(
min.instance,
text,
min.instance.searchScore,
null);
service.ask( // If there is some result, answer immediately.
min.instance,
text,
min.instance.searchScore,
null,
async resultsB => {
// If there is some result, answer immediately. if (resultsB && resultsB.answer) {
if (resultsB && resultsB.answer) { // Saves some context info.
// Saves some context info. const user = min.userState.get(dc.context);
user.isAsking = false;
user.lastQuestionId = resultsB.questionId;
const user = min.userState.get(dc.context); // Inform user that a broader search will be used.
user.isAsking = false;
user.lastQuestionId = resultsB.questionId;
// Inform user that a broader search will be used. if (user.subjects.length > 0) {
let subjectText =
if (user.subjects.length > 0) { `${KBService.getSubjectItemsSeparatedBySpaces(
let subjectText = user.subjects
`${KBService.getSubjectItemsSeparatedBySpaces( )}`;
user.subjects let messages = [
)}`; `Respondendo nao apenas sobre ${subjectText}... `,
let messages = [ `Respondendo de modo mais abrangente...`,
`Respondendo nao apenas sobre ${subjectText}... `, `Vou te responder de modo mais abrangente...
`Respondendo de modo mais abrangente...`,
`Vou te responder de modo mais abrangente...
Não apenas sobre ${subjectText}` Não apenas sobre ${subjectText}`
]; ];
dc.context.sendActivity(messages[0]); // TODO: Handle rnd. dc.context.sendActivity(messages[0]); // TODO: Handle rnd.
}
// Sends the answer to all outputs, including projector.
service.sendAnswer(min.conversationalService,
dc,
resultsB.answer
);
dc.replace("/ask", { isReturning: true });
} else {
await min.conversationalService.runNLP(
dc,
min,
text,
(data, error) => {
if (!data) {
let messages = [
"Desculpe-me, não encontrei nada a respeito.",
"Lamento... Não encontrei nada sobre isso. Vamos tentar novamente?",
"Desculpe-me, não achei nada parecido. Poderia tentar escrever de outra forma?"
];
dc.context.sendActivity(messages[0]); // TODO: Handle rnd.
dc.replace("/ask", { isReturning: true });
}
}).catch(err => {
console.log(err);
});
}
});
} }
// Sends the answer to all outputs, including projector.
service.sendAnswer(min.conversationalService,
dc,
resultsB.answer
);
dc.replace("/ask", { isReturning: true });
} else {
await min.conversationalService.runNLP(
dc,
min,
text,
(data, error) => {
if (!data) {
let messages = [
"Desculpe-me, não encontrei nada a respeito.",
"Lamento... Não encontrei nada sobre isso. Vamos tentar novamente?",
"Desculpe-me, não achei nada parecido. Poderia tentar escrever de outra forma?"
];
dc.context.sendActivity(messages[0]); // TODO: Handle rnd.
dc.replace("/ask", { isReturning: true });
}
}).catch(err => {
console.log(err);
});
} }
); }
} }
]); ]);

View file

@ -37,19 +37,19 @@ const Parse = require("csv-parse");
const Async = require("async"); const Async = require("async");
const UrlJoin = require("url-join"); const UrlJoin = require("url-join");
const Walk = require("fs-walk"); const Walk = require("fs-walk");
const WaitUntil = require("wait-until");
const marked = require("marked"); const marked = require("marked");
import { Sequelize } from "sequelize-typescript";
import { GBConfigService } from './../../core.gbapp/services/GBConfigService'; import { GBConfigService } from './../../core.gbapp/services/GBConfigService';
import { GuaribasQuestion, GuaribasAnswer, GuaribasSubject } from "../models"; import { GuaribasQuestion, GuaribasAnswer, GuaribasSubject } from "../models";
import { GBServiceCallback, IGBCoreService, IGBConversationalService, IGBInstance } from "botlib"; import { GBServiceCallback, IGBCoreService, IGBConversationalService, IGBInstance } from "botlib";
import { AzureSearch } from "pragmatismo-io-framework"; import { AzureSearch } from "pragmatismo-io-framework";
import { GBCoreService } from 'deploy/core.gbapp/services/GBCoreService';
import { GBDeployer } from "../../core.gbapp/services/GBDeployer"; import { GBDeployer } from "../../core.gbapp/services/GBDeployer";
import { GBConversationalService } from "../../core.gbapp/services/GBConversationalService";
import { GuaribasPackage } from "../../core.gbapp/models/GBModel"; import { GuaribasPackage } from "../../core.gbapp/models/GBModel";
export class KBServiceSearchResults {
answer: GuaribasAnswer;
questionId: number;
}
export class KBService { export class KBService {
getAnswerById( getAnswerById(
@ -103,75 +103,81 @@ export class KBService {
}); });
} }
ask( async ask(
instance: IGBInstance, instance: IGBInstance,
what: string, what: string,
searchScore: number, searchScore: number,
subjects: GuaribasSubject[], subjects: GuaribasSubject[]
cb: GBServiceCallback<any> ): Promise<KBServiceSearchResults> {
) {
// Builds search query. return new Promise<KBServiceSearchResults>((resolve, reject) => {
what = what.toLowerCase(); // Builds search query.
what = what.replace("?", " ");
what = what.replace("!", " ");
what = what.replace(".", " ");
what = what.replace("/", " ");
what = what.replace("\\", " ");
if (subjects) { what = what.toLowerCase();
let text = KBService.getSubjectItemsSeparatedBySpaces( what = what.replace("?", " ");
subjects what = what.replace("!", " ");
); what = what.replace(".", " ");
if (text){ what = what.replace("/", " ");
what = `${what} ${text}`; what = what.replace("\\", " ");
if (subjects) {
let text = KBService.getSubjectItemsSeparatedBySpaces(
subjects
);
if (text) {
what = `${what} ${text}`;
}
} }
}
// TODO: Filter by instance. what = `${what}&$filter=instanceId eq ${instanceId}`; // TODO: Filter by instance. what = `${what}&$filter=instanceId eq ${instanceId}`;
// Performs search. // Performs search.
var _this_ = this; var _this_ = this;
if (instance.searchKey && GBConfigService.get("DATABASE_DIALECT") == "mssql") { if (instance.searchKey && GBConfigService.get("DATABASE_DIALECT") == "mssql") {
let service = new AzureSearch( let service = new AzureSearch(
instance.searchKey, instance.searchKey,
instance.searchHost, instance.searchHost,
instance.searchIndex, instance.searchIndex,
instance.searchIndexer instance.searchIndexer
); );
service.search(what, (err: any, results: any) => { service.search(what, (err: any, results: any) => {
if (results && results.length > 0) { if (results && results.length > 0) {
// Ponders over configuration. // Ponders over configuration.
if (results[0]["@search.score"] >= searchScore) { if (results[0]["@search.score"] >= searchScore) {
_this_.getAnswerById( _this_.getAnswerById(
instance.instanceId, instance.instanceId,
results[0].answerId, results[0].answerId,
(answer, err) => { (answer, err) => {
cb({ answer: answer, questionId: results[0].questionId }, null); if (err) { reject(err); } else {
} resolve({ answer: answer, questionId: results[0].questionId });
); }
}
);
} else {
resolve(null);
}
} else { } else {
cb(null, null); resolve(null);
} }
} else { });
cb(null, null); } else {
} this.getAnswerByText(instance.instanceId, what, (data, err) => {
}); if (data) {
} else { resolve({ answer: data.answer, questionId: data.question.questionId });
this.getAnswerByText(instance.instanceId, what, (data, err) => { }
if (data) { else {
cb({ answer: data.answer, questionId: data.question.questionId }, null); if (err) { reject(err); } else {
} resolve(null);
else { }
cb(null, err); }
} });
}); }
} });
} }
getSearchSchema(indexName) { getSearchSchema(indexName) {