Skip to content

Commit

Permalink
[QnA Maker] Support for IsTest and RankerType in GetAnswerAsync call …
Browse files Browse the repository at this point in the history
…in QnAMaker (#1478)
  • Loading branch information
gurvsing authored Dec 6, 2019
1 parent fe85099 commit aa2723a
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 4 deletions.
10 changes: 10 additions & 0 deletions libraries/botbuilder-ai/src/qnamaker-interfaces/qnamakerOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,14 @@ export interface QnAMakerOptions {
* Id of the current question asked.
*/
qnaId?: number;

/**
* A value indicating whether to call test or prod environment of knowledgebase.
*/
isTest?: boolean;

/**
* Ranker types.
*/
rankerType?: string;
}
28 changes: 28 additions & 0 deletions libraries/botbuilder-ai/src/qnamaker-interfaces/rankerTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* @module botbuilder-ai
*/
/**
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/

/**
* Enumeration of types of ranking.
*/
export class RankerTypes {

/**
* Default Ranker Behaviour. i.e. Ranking based on Questions and Answer.
*/
public static readonly default: string = 'Default';

/**
* Ranker based on question Only.
*/
public static readonly questionOnly: string = 'QuestionOnly';

/**
* Ranker based on Autosuggest for question field Only.
*/
public static readonly autoSuggestQuestion: string = 'AutoSuggestQuestion';
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { QnARequestContext } from '../qnamaker-interfaces/qnaRequestContext';
import { HttpRequestUtils } from './httpRequestUtils';

import { QNAMAKER_TRACE_TYPE, QNAMAKER_TRACE_LABEL, QNAMAKER_TRACE_NAME } from '..';
import { RankerTypes } from '../qnamaker-interfaces/rankerTypes';

/**
* Generate Answer api utils class.
Expand Down Expand Up @@ -58,8 +59,9 @@ export class GenerateAnswerUtils {
*/
public async queryQnaServiceRaw(endpoint: QnAMakerEndpoint, question: string, options?: QnAMakerOptions): Promise<QnAMakerResults> {
const url: string = `${ endpoint.host }/knowledgebases/${ endpoint.knowledgeBaseId }/generateanswer`;
const queryOptions: QnAMakerOptions = { ...this._options, ...options } as QnAMakerOptions;

var queryOptions: QnAMakerOptions = { ...this._options, ...options } as QnAMakerOptions;

queryOptions.rankerType = !queryOptions.rankerType ? RankerTypes.default : queryOptions.rankerType;
this.validateOptions(queryOptions);

var payloadBody = JSON.stringify({
Expand Down Expand Up @@ -109,8 +111,8 @@ export class GenerateAnswerUtils {
*
* @param options (Optional) The options for the QnA Maker knowledge base. If null, constructor option is used for this instance.
*/
public validateOptions(options: QnAMakerOptions): void {
const { scoreThreshold, top } = options;
public validateOptions(options: QnAMakerOptions) {
const { scoreThreshold, top, rankerType } = options;

if (scoreThreshold) {
this.validateScoreThreshold(scoreThreshold);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"activeLearningEnabled": true,
"answers": [
{
"questions": [],
"answer": "No good match found in KB.",
"score": 0,
"id": -1,
"source": null,
"metadata": []
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"activeLearningEnabled": false,
"answers": [
{
"questions": [
"Q1"
],
"answer": "A1",
"score": 80,
"id": 15,
"source": "Editorial",
"metadata": [
{
"name": "topic",
"value": "value"
}
]
},
{
"questions": [
"Q2"
],
"answer": "A2",
"score": 78,
"id": 16,
"source": "Editorial",
"metadata": [
{
"name": "topic",
"value": "value"
}
]
}
]
}
20 changes: 20 additions & 0 deletions libraries/botbuilder-ai/tests/qnaMaker.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,26 @@ describe('QnAMaker', function () {
assert.strictEqual(qnaResults[0].score < 1, true, 'score should be low');
});

it('should call qnamaker with isTest true', async function() {
const qna = new QnAMaker(endpoint);
const turnContext = new TestContext({ text: "Q11" });
const options = { top: 1, context: null, isTest: true };

const qnaResults = await qna.getAnswers(turnContext, options);

assert.strictEqual(qnaResults.length, 0, 'no answers should be returned');
});

it('should call qnamaker with rankerType questionOnly', async function() {
const qna = new QnAMaker(endpoint);
const turnContext = new TestContext({ text: "Q11" });
const options = { top: 1, context: null, rankerType: "questionOnly" };

const qnaResults = await qna.getAnswers(turnContext, options);

assert.strictEqual(qnaResults.length, 2, 'no answers should be returned');
});

it('should return answer with timeout option specified', async function() {
const timeoutOption = { timeout: 500000 };
const qna = new QnAMaker(endpoint, timeoutOption);
Expand Down

0 comments on commit aa2723a

Please sign in to comment.