Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Botbuilder-ai bugs #4208

Merged
merged 5 commits into from
Apr 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 3 additions & 10 deletions libraries/botbuilder-ai/src/qnaMaker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,6 @@ export class QnAMaker implements QnAMakerClient, QnAMakerTelemetryClient {
telemetryProperties?: { [key: string]: string },
telemetryMetrics?: { [key: string]: number }
): Promise<QnAMakerResults> {
const queryResult: QnAMakerResult[] = [] as QnAMakerResult[];
const question: string = this.getTrimmedMessageText(context);
const queryOptions: QnAMakerOptions = { ...this._options, ...options } as QnAMakerOptions;

Expand All @@ -270,12 +269,6 @@ export class QnAMaker implements QnAMakerClient, QnAMakerTelemetryClient {

if (question.length > 0) {
result = await this.generateAnswerUtils.queryQnaServiceRaw(this.endpoint, question, queryOptions);

const sortedQnaAnswers: QnAMakerResult[] = GenerateAnswerUtils.sortAnswersWithinThreshold(
result.answers,
queryOptions
);
queryResult.push(...sortedQnaAnswers);
}

if (!result) {
Expand All @@ -284,13 +277,13 @@ export class QnAMaker implements QnAMakerClient, QnAMakerTelemetryClient {

await Promise.all([
// Log telemetry
this.onQnaResults(queryResult, context, telemetryProperties, telemetryMetrics),
this.generateAnswerUtils.emitTraceInfo(context, queryResult, queryOptions),
this.onQnaResults(result?.answers, context, telemetryProperties, telemetryMetrics),
this.generateAnswerUtils.emitTraceInfo(context, result?.answers, queryOptions),
]);

const qnaResponse: QnAMakerResults = {
activeLearningEnabled: result.activeLearningEnabled,
answers: queryResult,
answers: result?.answers,
};

return qnaResponse;
Expand Down
26 changes: 12 additions & 14 deletions libraries/botbuilder-ai/src/qnaMakerDialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -731,12 +731,14 @@ export class QnAMakerDialog extends WaterfallDialog implements QnAMakerDialogCon
if (response?.length > 0) {
const activity = dialogOptions.qnaDialogResponseOptions.noAnswer;
if (response[0].id !== -1) {
await step.context.sendActivity(response[0].answer);
const message = QnACardBuilder.getQnAAnswerCard(response[0], this.displayPreciseAnswerOnly);
await step.context.sendActivity(message);
} else {
if (activity && activity.text) {
await step.context.sendActivity(activity);
} else {
await step.context.sendActivity(response[0].answer);
const message = QnACardBuilder.getQnAAnswerCard(response[0], this.displayPreciseAnswerOnly);
await step.context.sendActivity(message);
}
}
} else {
Expand Down Expand Up @@ -906,22 +908,18 @@ export class QnAMakerDialog extends WaterfallDialog implements QnAMakerDialogCon

if (response?.length > 0 && response[0].id != -1) {
const answer = response[0];
if (answer.answerSpan?.text || answer?.context?.prompts?.length > 0) {
if (answer?.context?.prompts?.length > 0) {
const previousContextData: { [key: string]: number } = {};
if (answer?.context?.prompts?.length > 0) {
const previousContextData: { [key: string]: number } = {};

answer.context.prompts.forEach((prompt) => {
previousContextData[prompt.displayText] = prompt.qnaId;
});

step.activeDialog.state[this.qnAContextData] = previousContextData;
step.activeDialog.state[this.previousQnAId] = answer.id;
step.activeDialog.state[this.options] = dialogOptions;
}
answer.context.prompts.forEach((prompt) => {
previousContextData[prompt.displayText] = prompt.qnaId;
});

step.activeDialog.state[this.qnAContextData] = previousContextData;
step.activeDialog.state[this.previousQnAId] = answer.id;
step.activeDialog.state[this.options] = dialogOptions;
const message = QnACardBuilder.getQnAAnswerCard(answer, this.displayPreciseAnswerOnly);
await step.context.sendActivity(message);

return Dialog.EndOfTurn;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,25 +159,6 @@ export class GenerateAnswerUtils {
}
}

/**
* Sorts all QnAMakerResult from highest-to-lowest scoring.
* Filters QnAMakerResults within threshold specified (default threshold: .001).
*
* @param {QnAMakerResult[]} answers Answers returned by QnA Maker.
* @param {QnAMakerOptions} queryOptions (Optional) The options for the QnA Maker knowledge base. If null, constructor option is used for this instance.
* @returns {QnAMakerResult[]} the sorted and filtered results
*/
static sortAnswersWithinThreshold(
answers: QnAMakerResult[] = [] as QnAMakerResult[],
queryOptions: QnAMakerOptions
): QnAMakerResult[] {
const minScore: number = typeof queryOptions.scoreThreshold === 'number' ? queryOptions.scoreThreshold : 0.001;

return answers
.filter((ans: QnAMakerResult) => ans.score >= minScore)
.sort((a: QnAMakerResult, b: QnAMakerResult) => b.score - a.score);
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
private formatQnaResult(qnaResult: QnAMakerResults | any): QnAMakerResults {
qnaResult.answers = qnaResult.answers.map((answer: QnAMakerResult & { qnaId?: number }) => {
Expand Down
15 changes: 8 additions & 7 deletions libraries/botbuilder-ai/tests/qnaMaker.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ describe('QnAMaker', function () {

const results = await qna.getAnswers(context, options);

assert.strictEqual(results.length, 0);
assert.strictEqual(results.length, 1);
});

it('calls qnamaker with rankerType questionOnly', async function () {
Expand All @@ -312,7 +312,7 @@ describe('QnAMaker', function () {

const results = await qna.getAnswers(context, options);

assert.strictEqual(results.length, 0);
assert.strictEqual(results.length, 1);
});

it('returns answer with timeout option specified', async function () {
Expand Down Expand Up @@ -456,14 +456,14 @@ describe('QnAMaker', function () {
sinon.match({
name: 'QnaMessage',
properties: sinon.match({
answer: sinon.match.string,
articleFound: 'false',
knowledgeBaseId,
matchedQuestion: 'No Qna Question matched',
question: 'where are the unicorns?',
questionId: 'No Qna Question Id matched',
username: sinon.match.string,
questionId: '-1',
answer: sinon.match.string,
articleFound: 'true',
}),
metrics: { score: 0 },
})
)
.once();
Expand All @@ -475,7 +475,8 @@ describe('QnAMaker', function () {

sandbox.verify();
assert(qna.logPersonalInformation);
assert.deepStrictEqual(results, []);
assert.strictEqual(results.length, 1);
assert.strictEqual(results[0].answer, 'No good match found in KB.');
});

it('does not log telemetry pii', async function () {
Expand Down