diff --git a/libraries/bot-ai-qna/pom.xml b/libraries/bot-ai-qna/pom.xml
index 4de263b57..189aa41c2 100644
--- a/libraries/bot-ai-qna/pom.xml
+++ b/libraries/bot-ai-qna/pom.xml
@@ -49,14 +49,20 @@
junit
junit
+
+ org.mockito
+ mockito-core
+
+
org.slf4j
slf4j-api
+
com.microsoft.bot
- bot-builder
- ${project.version}
+ bot-integration-spring
+ compile
com.microsoft.bot
@@ -69,27 +75,16 @@
test-jar
test
-
- com.microsoft.bot
- bot-integration-spring
- 4.6.0-preview8
- compile
-
+
com.squareup.okhttp3
okhttp
- 4.9.0
com.squareup.okhttp3
mockwebserver
- 4.9.0
test
-
- org.mockito
- mockito-core
-
diff --git a/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/QnAMaker.java b/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/QnAMaker.java
index b6b5d3d1d..821cf0196 100644
--- a/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/QnAMaker.java
+++ b/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/QnAMaker.java
@@ -16,6 +16,7 @@
import com.microsoft.bot.builder.BotTelemetryClient;
import com.microsoft.bot.builder.NullBotTelemetryClient;
import com.microsoft.bot.builder.TurnContext;
+import com.microsoft.bot.connector.Async;
import com.microsoft.bot.restclient.serializer.JacksonAdapter;
import com.microsoft.bot.schema.Activity;
import com.microsoft.bot.schema.ActivityTypes;
@@ -75,8 +76,12 @@ public class QnAMaker implements QnAMakerClient, TelemetryQnAMaker {
* identifiable information in telemetry
* events.
*/
- public QnAMaker(QnAMakerEndpoint withEndpoint, QnAMakerOptions options,
- BotTelemetryClient withTelemetryClient, Boolean withLogPersonalInformation) {
+ public QnAMaker(
+ QnAMakerEndpoint withEndpoint,
+ QnAMakerOptions options,
+ BotTelemetryClient withTelemetryClient,
+ Boolean withLogPersonalInformation
+ ) {
if (withLogPersonalInformation == null) {
withLogPersonalInformation = false;
}
@@ -100,7 +105,8 @@ public QnAMaker(QnAMakerEndpoint withEndpoint, QnAMakerOptions options,
if (this.endpoint.getHost().endsWith("v2.0") || this.endpoint.getHost().endsWith("v3.0")) {
throw new UnsupportedOperationException(
- "v2.0 and v3.0 of QnA Maker service" + " is no longer supported in the QnA Maker.");
+ "v2.0 and v3.0 of QnA Maker service" + " is no longer supported in the QnA Maker."
+ );
}
this.telemetryClient = withTelemetryClient != null ? withTelemetryClient : new NullBotTelemetryClient();
@@ -113,8 +119,8 @@ public QnAMaker(QnAMakerEndpoint withEndpoint, QnAMakerOptions options,
/**
* Initializes a new instance of the {@link QnAMaker} class.
*
- * @param withEndpoint The endpoint of the knowledge base to query.
- * @param options The options for the QnA Maker knowledge base.
+ * @param withEndpoint The endpoint of the knowledge base to query.
+ * @param options The options for the QnA Maker knowledge base.
*/
public QnAMaker(QnAMakerEndpoint withEndpoint, @Nullable QnAMakerOptions options) {
this(withEndpoint, options, null, null);
@@ -170,10 +176,14 @@ public CompletableFuture getAnswers(TurnContext turnContext, @Nul
* @return A list of answers for the user query, sorted in decreasing order of
* ranking score.
*/
- public CompletableFuture getAnswers(TurnContext turnContext, QnAMakerOptions options,
- Map telemetryProperties, @Nullable Map telemetryMetrics) {
+ public CompletableFuture getAnswers(
+ TurnContext turnContext,
+ QnAMakerOptions options,
+ Map telemetryProperties,
+ @Nullable Map telemetryMetrics
+ ) {
return this.getAnswersRaw(turnContext, options, telemetryProperties, telemetryMetrics)
- .thenApply(result -> result.getAnswers());
+ .thenApply(result -> result.getAnswers());
}
/**
@@ -191,22 +201,29 @@ public CompletableFuture getAnswers(TurnContext turnContext, QnAM
* @return A list of answers for the user query, sorted in decreasing order of
* ranking score.
*/
- public CompletableFuture getAnswersRaw(TurnContext turnContext, QnAMakerOptions options,
- @Nullable Map telemetryProperties, @Nullable Map telemetryMetrics) {
+ public CompletableFuture getAnswersRaw(
+ TurnContext turnContext,
+ QnAMakerOptions options,
+ @Nullable Map telemetryProperties,
+ @Nullable Map telemetryMetrics
+ ) {
if (turnContext == null) {
- throw new IllegalArgumentException("turnContext");
+ return Async.completeExceptionally(new IllegalArgumentException("turnContext"));
}
if (turnContext.getActivity() == null) {
- throw new IllegalArgumentException(
- String.format("The %1$s property for %2$s can't be null.", "Activity", "turnContext"));
+ return Async.completeExceptionally(
+ new IllegalArgumentException(
+ String.format("The %1$s property for %2$s can't be null.", "Activity", "turnContext")
+ )
+ );
}
Activity messageActivity = turnContext.getActivity();
if (messageActivity == null || !messageActivity.isType(ActivityTypes.MESSAGE)) {
- throw new IllegalArgumentException("Activity type is not a message");
+ return Async.completeExceptionally(new IllegalArgumentException("Activity type is not a message"));
}
if (Strings.isNullOrEmpty(turnContext.getActivity().getText())) {
- throw new IllegalArgumentException("Null or empty text");
+ return Async.completeExceptionally(new IllegalArgumentException("Null or empty text"));
}
return this.generateAnswerHelper.getAnswersRaw(turnContext, messageActivity, options).thenCompose(result -> {
@@ -253,14 +270,19 @@ public CompletableFuture callTrain(FeedbackRecords feedbackRecords) throws
* @return A Task representing the work to be executed.
* @throws IOException Throws an IOException if there is any.
*/
- protected CompletableFuture onQnaResults(QueryResult[] queryResults, TurnContext turnContext,
- @Nullable Map telemetryProperties, @Nullable Map telemetryMetrics)
- throws IOException {
- return fillQnAEvent(queryResults, turnContext, telemetryProperties, telemetryMetrics).thenAccept(eventData -> {
- // Track the event
- this.telemetryClient.trackEvent(QnATelemetryConstants.QNA_MSG_EVENT, eventData.getLeft(),
- eventData.getRight());
- });
+ protected CompletableFuture onQnaResults(
+ QueryResult[] queryResults,
+ TurnContext turnContext,
+ @Nullable Map telemetryProperties,
+ @Nullable Map telemetryMetrics
+ ) throws IOException {
+ return fillQnAEvent(queryResults, turnContext, telemetryProperties, telemetryMetrics).thenAccept(
+ eventData -> {
+ // Track the event
+ this.telemetryClient
+ .trackEvent(QnATelemetryConstants.QNA_MSG_EVENT, eventData.getLeft(), eventData.getRight());
+ }
+ );
}
/**
@@ -279,17 +301,20 @@ protected CompletableFuture onQnaResults(QueryResult[] queryResults, TurnC
* any properties passed from the GetAnswersAsync method.
* @throws IOException Throws an IOException if there is any.
*/
- protected CompletableFuture, Map>> fillQnAEvent(QueryResult[] queryResults,
- TurnContext turnContext, @Nullable Map telemetryProperties,
- @Nullable Map telemetryMetrics) throws IOException {
+ protected CompletableFuture, Map>> fillQnAEvent(
+ QueryResult[] queryResults,
+ TurnContext turnContext,
+ @Nullable Map telemetryProperties,
+ @Nullable Map telemetryMetrics
+ ) throws IOException {
Map properties = new HashMap();
Map metrics = new HashMap();
properties.put(QnATelemetryConstants.KNOWLEDGE_BASE_ID_PROPERTY, this.endpoint.getKnowledgeBaseId());
String text = turnContext.getActivity().getText();
- String userName = turnContext.getActivity().getFrom() != null
- ? turnContext.getActivity().getFrom().getName() : null;
+ String userName =
+ turnContext.getActivity().getFrom() != null ? turnContext.getActivity().getFrom().getName() : null;
// Use the LogPersonalInformation flag to toggle logging PII data, text and user
// name are common examples
@@ -307,9 +332,14 @@ protected CompletableFuture, Map>> fill
if (queryResults.length > 0) {
JacksonAdapter jacksonAdapter = new JacksonAdapter();
QueryResult queryResult = queryResults[0];
- properties.put(QnATelemetryConstants.MATCHED_QUESTION_PROPERTY,
- jacksonAdapter.serialize(queryResult.getQuestions()));
- properties.put(QnATelemetryConstants.QUESTION_ID_PROPERTY, queryResult.getId().toString());
+ properties.put(
+ QnATelemetryConstants.MATCHED_QUESTION_PROPERTY,
+ jacksonAdapter.serialize(queryResult.getQuestions())
+ );
+ properties.put(
+ QnATelemetryConstants.QUESTION_ID_PROPERTY,
+ queryResult.getId() != null ? queryResult.getId().toString() : ""
+ );
properties.put(QnATelemetryConstants.ANSWER_PROPERTY, queryResult.getAnswer());
metrics.put(QnATelemetryConstants.SCORE_PROPERTY, queryResult.getScore().doubleValue());
properties.put(QnATelemetryConstants.ARTICLE_FOUND_PROPERTY, "true");
@@ -323,13 +353,13 @@ protected CompletableFuture, Map>> fill
// Additional Properties can override "stock" properties.
if (telemetryProperties != null) {
Multimap multiMapTelemetryProperties = LinkedListMultimap.create();
- for (Entry entry: telemetryProperties.entrySet()) {
+ for (Entry entry : telemetryProperties.entrySet()) {
multiMapTelemetryProperties.put(entry.getKey(), entry.getValue());
}
- for (Entry entry: properties.entrySet()) {
+ for (Entry entry : properties.entrySet()) {
multiMapTelemetryProperties.put(entry.getKey(), entry.getValue());
}
- for (Entry> entry: multiMapTelemetryProperties.asMap().entrySet()) {
+ for (Entry> entry : multiMapTelemetryProperties.asMap().entrySet()) {
telemetryProperties.put(entry.getKey(), entry.getValue().iterator().next());
}
}
@@ -337,13 +367,13 @@ protected CompletableFuture, Map>> fill
// Additional Metrics can override "stock" metrics.
if (telemetryMetrics != null) {
Multimap multiMapTelemetryMetrics = LinkedListMultimap.create();
- for (Entry entry: telemetryMetrics.entrySet()) {
+ for (Entry entry : telemetryMetrics.entrySet()) {
multiMapTelemetryMetrics.put(entry.getKey(), entry.getValue());
}
- for (Entry entry: metrics.entrySet()) {
+ for (Entry entry : metrics.entrySet()) {
multiMapTelemetryMetrics.put(entry.getKey(), entry.getValue());
}
- for (Entry> entry: multiMapTelemetryMetrics.asMap().entrySet()) {
+ for (Entry> entry : multiMapTelemetryMetrics.asMap().entrySet()) {
telemetryMetrics.put(entry.getKey(), entry.getValue().iterator().next());
}
}
diff --git a/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/QnAMakerClient.java b/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/QnAMakerClient.java
index 55da459d9..e2299745c 100644
--- a/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/QnAMakerClient.java
+++ b/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/QnAMakerClient.java
@@ -33,8 +33,12 @@ public interface QnAMakerClient {
* @return A list of answers for the user query, sorted in decreasing order of
* ranking score.
*/
- CompletableFuture getAnswers(TurnContext turnContext, QnAMakerOptions options,
- Map telemetryProperties, @Nullable Map telemetryMetrics);
+ CompletableFuture getAnswers(
+ TurnContext turnContext,
+ QnAMakerOptions options,
+ Map telemetryProperties,
+ @Nullable Map telemetryMetrics
+ );
/**
* Generates an answer from the knowledge base.
@@ -51,8 +55,12 @@ CompletableFuture getAnswers(TurnContext turnContext, QnAMakerOpt
* @return A list of answers for the user query, sorted in decreasing order of
* ranking score.
*/
- CompletableFuture getAnswersRaw(TurnContext turnContext, QnAMakerOptions options,
- @Nullable Map telemetryProperties, @Nullable Map telemetryMetrics);
+ CompletableFuture getAnswersRaw(
+ TurnContext turnContext,
+ QnAMakerOptions options,
+ @Nullable Map telemetryProperties,
+ @Nullable Map telemetryMetrics
+ );
/**
* Filters the ambiguous question for active learning.
diff --git a/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/QnAMakerRecognizer.java b/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/QnAMakerRecognizer.java
index b93e7f788..6c1ddc55c 100644
--- a/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/QnAMakerRecognizer.java
+++ b/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/QnAMakerRecognizer.java
@@ -197,8 +197,8 @@ public Boolean getIsTest() {
* Sets a value indicating whether gets or sets environment of knowledgebase to
* be called.
*
- * @param withIsTest A value indicating whether to call test or prod environment of
- * knowledgebase.
+ * @param withIsTest A value indicating whether to call test or prod environment
+ * of knowledgebase.
*/
public void setIsTest(Boolean withIsTest) {
this.isTest = withIsTest;
@@ -234,8 +234,8 @@ public JoinOperator getStrictFiltersJoinOperator() {
/**
* Sets {@link Metadata} join operator.
*
- * @param withStrictFiltersJoinOperator A value used for Join operation of Metadata
- * {@link Metadata}.
+ * @param withStrictFiltersJoinOperator A value used for Join operation of
+ * Metadata {@link Metadata}.
*/
public void setStrictFiltersJoinOperator(JoinOperator withStrictFiltersJoinOperator) {
this.strictFiltersJoinOperator = withStrictFiltersJoinOperator;
@@ -290,7 +290,7 @@ public QnARequestContext getContext() {
* Sets an expression to evaluate to set the context.
*
* @param withContext An expression to evaluate to QnARequestContext to pass as
- * context.
+ * context.
*/
public void setContext(QnARequestContext withContext) {
this.context = withContext;
@@ -329,8 +329,8 @@ public Boolean getLogPersonalInformation() {
* Sets the flag to determine if personal information should be logged in
* telemetry.
*
- * @param withLogPersonalInformation The flag to indicate in personal information
- * should be logged in telemetry.
+ * @param withLogPersonalInformation The flag to indicate in personal
+ * information should be logged in telemetry.
*/
public void setLogPersonalInformation(Boolean withLogPersonalInformation) {
this.logPersonalInformation = withLogPersonalInformation;
@@ -351,8 +351,12 @@ public void setLogPersonalInformation(Boolean withLogPersonalInformation) {
* @return A {@link RecognizerResult} containing the QnA Maker result.
*/
@Override
- public CompletableFuture recognize(DialogContext dialogContext, Activity activity,
- Map telemetryProperties, Map telemetryMetrics) {
+ public CompletableFuture recognize(
+ DialogContext dialogContext,
+ Activity activity,
+ Map telemetryProperties,
+ Map telemetryMetrics
+ ) {
// Identify matched intents
RecognizerResult recognizerResult = new RecognizerResult();
recognizerResult.setText(activity.getText());
@@ -364,14 +368,11 @@ public CompletableFuture recognize(DialogContext dialogContext
List filters = new ArrayList();
// TODO this should be uncommented as soon as Expression is added in Java
- /* if (this.includeDialogNameInMetadata.getValue(dialogContext.getState())) {
- filters.add(new Metadata() {
- {
- setName("dialogName");
- setValue(dialogContext.getActiveDialog().getId());
- }
- });
- } */
+ /*
+ * if (this.includeDialogNameInMetadata.getValue(dialogContext.getState())) {
+ * filters.add(new Metadata() { { setName("dialogName");
+ * setValue(dialogContext.getActiveDialog().getId()); } }); }
+ */
// if there is $qna.metadata set add to filters
Metadata[] externalMetadata = this.metadata;
@@ -402,13 +403,13 @@ public CompletableFuture recognize(DialogContext dialogContext
}
Float internalTopAnswer = topAnswer.getScore();
if (topAnswer.getAnswer().trim().toUpperCase().startsWith(intentPrefix.toUpperCase())) {
- recognizerResult.getIntents().put(
- topAnswer.getAnswer().trim().substring(intentPrefix.length()).trim(),
- new IntentScore() {
- {
- setScore(internalTopAnswer);
- }
- });
+ recognizerResult.getIntents()
+ .put(topAnswer.getAnswer().trim().substring(
+ intentPrefix.length()).trim(),
+ new IntentScore() {{
+ setScore(internalTopAnswer);
+ }}
+ );
} else {
recognizerResult.getIntents().put(this.qnAMatchIntent, new IntentScore() {
{
@@ -440,9 +441,12 @@ public CompletableFuture recognize(DialogContext dialogContext
});
}
- this.trackRecognizerResult(dialogContext, "QnAMakerRecognizerResult", this
- .fillRecognizerResultTelemetryProperties(recognizerResult, telemetryProperties, dialogContext),
- telemetryMetrics);
+ this.trackRecognizerResult(
+ dialogContext,
+ "QnAMakerRecognizerResult",
+ this.fillRecognizerResultTelemetryProperties(recognizerResult, telemetryProperties, dialogContext),
+ telemetryMetrics
+ );
return recognizerResult;
});
});
@@ -473,8 +477,8 @@ protected CompletableFuture getQnAMakerClient(DialogContext dc)
}
};
- return CompletableFuture.completedFuture(
- new QnAMaker(endpoint, new QnAMakerOptions(), this.getTelemetryClient(), logPersonalInfo));
+ return CompletableFuture
+ .completedFuture(new QnAMaker(endpoint, new QnAMakerOptions(), this.getTelemetryClient(), logPersonalInfo));
}
/**
@@ -489,37 +493,53 @@ protected CompletableFuture getQnAMakerClient(DialogContext dc)
* on the TelemetryClient.
*/
@Override
- protected Map fillRecognizerResultTelemetryProperties(RecognizerResult recognizerResult,
- Map telemetryProperties, @Nullable DialogContext dialogContext) {
+ protected Map fillRecognizerResultTelemetryProperties(
+ RecognizerResult recognizerResult,
+ Map telemetryProperties,
+ @Nullable DialogContext dialogContext
+ ) {
if (dialogContext == null) {
throw new IllegalArgumentException(
- "dialogContext: DialogContext needed for state in "
- + "AdaptiveRecognizer.FillRecognizerResultTelemetryProperties method.");
+ "dialogContext: DialogContext needed for state in "
+ + "AdaptiveRecognizer.FillRecognizerResultTelemetryProperties method."
+ );
}
Map properties = new HashMap() {
{
- put("TopIntent",
- !recognizerResult.getIntents().isEmpty()
- ? (String) recognizerResult.getIntents().keySet().toArray()[0]
- : null);
- put("TopIntentScore",
- !recognizerResult.getIntents().isEmpty()
- ? Double.toString(
- ((IntentScore) recognizerResult.getIntents().values().toArray()[0]).getScore())
- : null);
- put("Intents",
- !recognizerResult.getIntents().isEmpty()
- ? Serialization.toStringSilent(recognizerResult.getIntents())
- : null);
- put("Entities",
- recognizerResult.getEntities() != null
- ? Serialization.toStringSilent(recognizerResult.getEntities())
- : null);
- put("AdditionalProperties",
- !recognizerResult.getProperties().isEmpty()
- ? Serialization.toStringSilent(recognizerResult.getProperties())
- : null);
+ put(
+ "TopIntent",
+ !recognizerResult.getIntents().isEmpty()
+ ? (String) recognizerResult.getIntents().keySet().toArray()[0]
+ : null
+ );
+ put(
+ "TopIntentScore",
+ !recognizerResult.getIntents()
+ .isEmpty()
+ ? Double.toString(
+ ((IntentScore) recognizerResult.getIntents().values().toArray()[0]).getScore()
+ )
+ : null
+ );
+ put(
+ "Intents",
+ !recognizerResult.getIntents().isEmpty()
+ ? Serialization.toStringSilent(recognizerResult.getIntents())
+ : null
+ );
+ put(
+ "Entities",
+ recognizerResult.getEntities() != null
+ ? Serialization.toStringSilent(recognizerResult.getEntities())
+ : null
+ );
+ put(
+ "AdditionalProperties",
+ !recognizerResult.getProperties().isEmpty()
+ ? Serialization.toStringSilent(recognizerResult.getProperties())
+ : null
+ );
}
};
@@ -531,10 +551,15 @@ protected Map fillRecognizerResultTelemetryProperties(Recognizer
// Additional Properties can override "stock properties".
if (telemetryProperties != null) {
telemetryProperties.putAll(properties);
- Map> telemetryPropertiesMap = telemetryProperties.entrySet().stream().collect(
- Collectors.groupingBy(Entry::getKey, Collectors.mapping(Entry::getValue, Collectors.toList())));
- return telemetryPropertiesMap.entrySet().stream()
- .collect(Collectors.toMap(Entry::getKey, e -> e.getValue().get(0)));
+ Map> telemetryPropertiesMap =
+ telemetryProperties.entrySet()
+ .stream()
+ .collect(
+ Collectors.groupingBy(Entry::getKey, Collectors.mapping(Entry::getValue, Collectors.toList()))
+ );
+ return telemetryPropertiesMap.entrySet()
+ .stream()
+ .collect(Collectors.toMap(Entry::getKey, e -> e.getValue().get(0)));
}
return properties;
diff --git a/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/TelemetryQnAMaker.java b/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/TelemetryQnAMaker.java
index 84152e768..3ad30ff83 100644
--- a/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/TelemetryQnAMaker.java
+++ b/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/TelemetryQnAMaker.java
@@ -50,6 +50,10 @@ public interface TelemetryQnAMaker {
* @return A list of answers for the user query, sorted in decreasing order of
* ranking score.
*/
- CompletableFuture getAnswers(TurnContext turnContext, QnAMakerOptions options,
- Map telemetryProperties, @Nullable Map telemetryMetrics);
+ CompletableFuture getAnswers(
+ TurnContext turnContext,
+ QnAMakerOptions options,
+ Map telemetryProperties,
+ @Nullable Map telemetryMetrics
+ );
}
diff --git a/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/dialogs/QnAMakerDialog.java b/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/dialogs/QnAMakerDialog.java
index 3a41b72cd..6459b2d70 100644
--- a/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/dialogs/QnAMakerDialog.java
+++ b/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/dialogs/QnAMakerDialog.java
@@ -3,6 +3,7 @@
package com.microsoft.bot.ai.qna.dialogs;
+import com.microsoft.bot.connector.Async;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
@@ -81,8 +82,8 @@ public class QnAMakerDialog extends WaterfallDialog {
private String cardNoMatchText;
@JsonProperty("cardNoMatchResponse")
- private BindToActivity cardNoMatchResponse = new BindToActivity(
- MessageFactory.text(DEFAULT_CARD_NO_MATCH_RESPONSE));
+ private BindToActivity cardNoMatchResponse =
+ new BindToActivity(MessageFactory.text(DEFAULT_CARD_NO_MATCH_RESPONSE));
@JsonProperty("strictFilters")
private Metadata[] strictFilters;
@@ -472,10 +473,20 @@ public void setRankerType(String withRankerType) {
* default client.
*/
@SuppressWarnings("checkstyle:ParameterNumber")
- public QnAMakerDialog(String dialogId, String withKnowledgeBaseId, String withEndpointKey, String withHostName,
- @Nullable Activity withNoAnswer, Float withThreshold, String withActiveLearningCardTitle,
- String withCardNoMatchText, Integer withTop, @Nullable Activity withCardNoMatchResponse,
- @Nullable Metadata[] withStrictFilters, @Nullable OkHttpClient withHttpClient) {
+ public QnAMakerDialog(
+ String dialogId,
+ String withKnowledgeBaseId,
+ String withEndpointKey,
+ String withHostName,
+ @Nullable Activity withNoAnswer,
+ Float withThreshold,
+ String withActiveLearningCardTitle,
+ String withCardNoMatchText,
+ Integer withTop,
+ @Nullable Activity withCardNoMatchResponse,
+ @Nullable Metadata[] withStrictFilters,
+ @Nullable OkHttpClient withHttpClient
+ ) {
super(dialogId, null);
if (knowledgeBaseId == null) {
throw new IllegalArgumentException("knowledgeBaseId");
@@ -491,14 +502,17 @@ public QnAMakerDialog(String dialogId, String withKnowledgeBaseId, String withEn
this.endpointKey = withEndpointKey;
this.threshold = withThreshold != null ? withThreshold : DEFAULT_THRESHOLD;
this.top = withTop != null ? withTop : DEFAULT_TOP_N;
- this.activeLearningCardTitle = withActiveLearningCardTitle != null ? withActiveLearningCardTitle
- : DEFAULT_CARD_TITLE;
+ this.activeLearningCardTitle =
+ withActiveLearningCardTitle != null ? withActiveLearningCardTitle : DEFAULT_CARD_TITLE;
this.cardNoMatchText = withCardNoMatchText != null ? withCardNoMatchText : DEFAULT_CARD_NO_MATCH_TEXT;
this.strictFilters = withStrictFilters;
- this.noAnswer = new BindToActivity(
- withNoAnswer != null ? withNoAnswer : MessageFactory.text(DEFAULT_NO_ANSWER));
- this.cardNoMatchResponse = new BindToActivity(withCardNoMatchResponse != null ? withCardNoMatchResponse
- : MessageFactory.text(DEFAULT_CARD_NO_MATCH_RESPONSE));
+ this.noAnswer =
+ new BindToActivity(withNoAnswer != null ? withNoAnswer : MessageFactory.text(DEFAULT_NO_ANSWER));
+ this.cardNoMatchResponse = new BindToActivity(
+ withCardNoMatchResponse != null
+ ? withCardNoMatchResponse
+ : MessageFactory.text(DEFAULT_CARD_NO_MATCH_RESPONSE)
+ );
this.httpClient = withHttpClient;
// add waterfall steps
@@ -542,14 +556,33 @@ public QnAMakerDialog(String dialogId, String withKnowledgeBaseId, String withEn
* default client.
*/
@SuppressWarnings("checkstyle:ParameterNumber")
- public QnAMakerDialog(String withKnowledgeBaseId, String withEndpointKey, String withHostName,
- @Nullable Activity withNoAnswer, Float withThreshold, String withActiveLearningCardTitle,
- String withCardNoMatchText, Integer withTop, @Nullable Activity withCardNoMatchResponse,
- @Nullable Metadata[] withStrictFilters,
- @Nullable OkHttpClient withHttpClient) {
- this(QnAMakerDialog.class.getName(), withKnowledgeBaseId, withEndpointKey, withHostName, withNoAnswer,
- withThreshold, withActiveLearningCardTitle, withCardNoMatchText, withTop, withCardNoMatchResponse,
- withStrictFilters, withHttpClient);
+ public QnAMakerDialog(
+ String withKnowledgeBaseId,
+ String withEndpointKey,
+ String withHostName,
+ @Nullable Activity withNoAnswer,
+ Float withThreshold,
+ String withActiveLearningCardTitle,
+ String withCardNoMatchText,
+ Integer withTop,
+ @Nullable Activity withCardNoMatchResponse,
+ @Nullable Metadata[] withStrictFilters,
+ @Nullable OkHttpClient withHttpClient
+ ) {
+ this(
+ QnAMakerDialog.class.getName(),
+ withKnowledgeBaseId,
+ withEndpointKey,
+ withHostName,
+ withNoAnswer,
+ withThreshold,
+ withActiveLearningCardTitle,
+ withCardNoMatchText,
+ withTop,
+ withCardNoMatchResponse,
+ withStrictFilters,
+ withHttpClient
+ );
}
/**
@@ -570,7 +603,7 @@ public QnAMakerDialog(String withKnowledgeBaseId, String withEndpointKey, String
@Override
public CompletableFuture beginDialog(DialogContext dc, @Nullable Object options) {
if (dc == null) {
- throw new IllegalArgumentException("dc");
+ return Async.completeExceptionally(new IllegalArgumentException("dc"));
}
if (!dc.getContext().getActivity().isType(ActivityTypes.MESSAGE)) {
@@ -622,7 +655,7 @@ protected CompletableFuture onPreBubbleEvent(DialogContext dc, DialogEv
String reply = dc.getContext().getActivity().getText();
QnAMakerDialogOptions dialogOptions = (QnAMakerDialogOptions) ObjectPath
- .getPathValue(dc.getActiveDialog().getState(), OPTIONS, QnAMakerDialogOptions.class);
+ .getPathValue(dc.getActiveDialog().getState(), OPTIONS, QnAMakerDialogOptions.class);
if (reply.equalsIgnoreCase(dialogOptions.getResponseOptions().getCardNoMatchText())) {
// it matches nomatch text, we like that.
@@ -630,8 +663,10 @@ protected CompletableFuture onPreBubbleEvent(DialogContext dc, DialogEv
}
List suggestedQuestions = (List) dc.getState().get("this.suggestedQuestions");
- if (suggestedQuestions != null && suggestedQuestions.stream()
- .anyMatch(question -> question.compareToIgnoreCase(reply.trim()) == 0)) {
+ if (
+ suggestedQuestions != null
+ && suggestedQuestions.stream().anyMatch(question -> question.compareToIgnoreCase(reply.trim()) == 0)
+ ) {
// it matches one of the suggested actions, we like that.
return CompletableFuture.completedFuture(true);
}
@@ -640,16 +675,17 @@ protected CompletableFuture onPreBubbleEvent(DialogContext dc, DialogEv
return this.getQnAMakerClient(dc).thenCompose(qnaClient -> {
QnAMakerDialog.resetOptions(dc, dialogOptions);
- return qnaClient.getAnswersRaw(dc.getContext(), dialogOptions.getQnAMakerOptions(),
- null, null)
- .thenApply(response -> {
+ return qnaClient.getAnswersRaw(dc.getContext(), dialogOptions.getQnAMakerOptions(), null, null)
+ .thenApply(
+ response -> {
// cache result so step doesn't have to do it again, this is a turn cache and we
// use hashcode so we don't conflict with any other qnamakerdialogs out there.
dc.getState().setValue(String.format("turn.qnaresult%s", this.hashCode()), response);
// disable interruption if we have answers.
return !(response.getAnswers().length == 0);
- });
+ }
+ );
});
}
// call base for default behavior.
@@ -657,8 +693,7 @@ protected CompletableFuture onPreBubbleEvent(DialogContext dc, DialogEv
}
/**
- * Gets an {@link QnAMakerClient} to use to access the QnA Maker knowledge
- * base.
+ * Gets an {@link QnAMakerClient} to use to access the QnA Maker knowledge base.
*
* @param dc The {@link DialogContext} for the current turn of conversation.
* @return A Task representing the asynchronous operation. If the task is
@@ -679,8 +714,9 @@ protected CompletableFuture getQnAMakerClient(DialogContext dc)
}
};
- return this.getQnAMakerOptions(dc).thenApply(options -> new QnAMaker(endpoint, options,
- this.getTelemetryClient(), this.logPersonalInformation));
+ return this.getQnAMakerOptions(
+ dc
+ ).thenApply(options -> new QnAMaker(endpoint, options, this.getTelemetryClient(), this.logPersonalInformation));
}
/**
@@ -717,12 +753,10 @@ protected CompletableFuture getQnAResponseOptions(Dial
return CompletableFuture.completedFuture(new QnADialogResponseOptions() {
{
setNoAnswer(noAnswer.bind(dc, dc.getState()).join());
- setActiveLearningCardTitle(activeLearningCardTitle != null
- ? activeLearningCardTitle
- : DEFAULT_CARD_TITLE);
- setCardNoMatchText(
- cardNoMatchText != null ? cardNoMatchText
- : DEFAULT_CARD_NO_MATCH_TEXT);
+ setActiveLearningCardTitle(
+ activeLearningCardTitle != null ? activeLearningCardTitle : DEFAULT_CARD_TITLE
+ );
+ setCardNoMatchText(cardNoMatchText != null ? cardNoMatchText : DEFAULT_CARD_NO_MATCH_TEXT);
setCardNoMatchResponse(cardNoMatchResponse.bind(dc, null).join());
}
});
@@ -736,8 +770,8 @@ protected CompletableFuture getQnAResponseOptions(Dial
* @return An object of Task of type {@link DialogTurnResult}.
*/
protected CompletableFuture displayQnAResult(WaterfallStepContext stepContext) {
- QnAMakerDialogOptions dialogOptions = ObjectPath.getPathValue(stepContext.getActiveDialog().getState(),
- OPTIONS, QnAMakerDialogOptions.class);
+ QnAMakerDialogOptions dialogOptions =
+ ObjectPath.getPathValue(stepContext.getActiveDialog().getState(), OPTIONS, QnAMakerDialogOptions.class);
String reply = stepContext.getContext().getActivity().getText();
if (reply.compareToIgnoreCase(dialogOptions.getResponseOptions().getCardNoMatchText()) == 0) {
Activity activity = dialogOptions.getResponseOptions().getCardNoMatchResponse();
@@ -751,8 +785,8 @@ protected CompletableFuture displayQnAResult(WaterfallStepCont
}
// If previous QnAId is present, replace the dialog
- Integer previousQnAId = ObjectPath.getPathValue(stepContext.getActiveDialog().getState(), PREVIOUS_QNA_ID,
- Integer.class, 0);
+ Integer previousQnAId =
+ ObjectPath.getPathValue(stepContext.getActiveDialog().getState(), PREVIOUS_QNA_ID, Integer.class, 0);
if (previousQnAId > 0) {
// restart the waterfall to step 0
return this.runStep(stepContext, 0, DialogReason.BEGIN_CALLED, null);
@@ -781,10 +815,10 @@ private static void resetOptions(DialogContext dc, QnAMakerDialogOptions dialogO
// -Check if previous context is present, if yes then put it with the query
// -Check for id if query is present in reverse index.
- Map previousContextData = ObjectPath.getPathValue(dc.getActiveDialog().getState(),
- QNA_CONTEXT_DATA, Map.class);
- Integer previousQnAId = ObjectPath.getPathValue(dc.getActiveDialog().getState(), PREVIOUS_QNA_ID,
- Integer.class, 0);
+ Map previousContextData =
+ ObjectPath.getPathValue(dc.getActiveDialog().getState(), QNA_CONTEXT_DATA, Map.class);
+ Integer previousQnAId =
+ ObjectPath.getPathValue(dc.getActiveDialog().getState(), PREVIOUS_QNA_ID, Integer.class, 0);
if (previousQnAId > 0) {
dialogOptions.getQnAMakerOptions().setContext(new QnARequestContext() {
@@ -804,8 +838,8 @@ private CompletableFuture callGenerateAnswer(WaterfallStepCont
// clear suggestedQuestions between turns.
stepContext.getState().removeValue("this.suggestedQuestions");
- QnAMakerDialogOptions dialogOptions = ObjectPath.getPathValue(stepContext.getActiveDialog().getState(),
- OPTIONS, QnAMakerDialogOptions.class);
+ QnAMakerDialogOptions dialogOptions =
+ ObjectPath.getPathValue(stepContext.getActiveDialog().getState(), OPTIONS, QnAMakerDialogOptions.class);
QnAMakerDialog.resetOptions(stepContext, dialogOptions);
// Storing the context info
@@ -813,12 +847,12 @@ private CompletableFuture callGenerateAnswer(WaterfallStepCont
// Calling QnAMaker to get response.
return this.getQnAMakerClient(stepContext).thenApply(qnaMakerClient -> {
- QueryResults response = (QueryResults) stepContext.getState()
- .get(String.format("turn.qnaresult%s", this.hashCode()));
+ QueryResults response =
+ (QueryResults) stepContext.getState().get(String.format("turn.qnaresult%s", this.hashCode()));
if (response == null) {
- response = qnaMakerClient.getAnswersRaw(stepContext.getContext(), dialogOptions.getQnAMakerOptions(),
- null, null)
- .join();
+ response = qnaMakerClient
+ .getAnswersRaw(stepContext.getContext(), dialogOptions.getQnAMakerOptions(), null, null)
+ .join();
}
// Resetting previous query.
@@ -833,8 +867,10 @@ private CompletableFuture callGenerateAnswer(WaterfallStepCont
// Check if active learning is enabled.
// MaximumScoreForLowScoreVariation is the score above which no need to check
// for feedback.
- if (response.getAnswers().length > 0 && response.getAnswers()[0]
- .getScore() <= (ActiveLearningUtils.getMaximumScoreForLowScoreVariation() / PERCENTAGE_DIVISOR)) {
+ if (
+ response.getAnswers().length > 0 && response.getAnswers()[0]
+ .getScore() <= (ActiveLearningUtils.getMaximumScoreForLowScoreVariation() / PERCENTAGE_DIVISOR)
+ ) {
// Get filtered list of the response that support low score variation criteria.
response.setAnswers(qnaMakerClient.getLowScoreVariation(response.getAnswers()));
@@ -845,9 +881,11 @@ private CompletableFuture callGenerateAnswer(WaterfallStepCont
}
// Get active learning suggestion card activity.
- Activity message = QnACardBuilder.getSuggestionsCard(suggestedQuestions,
- dialogOptions.getResponseOptions().getActiveLearningCardTitle(),
- dialogOptions.getResponseOptions().getCardNoMatchText());
+ Activity message = QnACardBuilder.getSuggestionsCard(
+ suggestedQuestions,
+ dialogOptions.getResponseOptions().getActiveLearningCardTitle(),
+ dialogOptions.getResponseOptions().getCardNoMatchText()
+ );
stepContext.getContext().sendActivity(message).join();
ObjectPath.setPathValue(stepContext.getActiveDialog().getState(), OPTIONS, dialogOptions);
@@ -870,33 +908,37 @@ private CompletableFuture callGenerateAnswer(WaterfallStepCont
}
private CompletableFuture callTrain(WaterfallStepContext stepContext) {
- QnAMakerDialogOptions dialogOptions = ObjectPath.getPathValue(stepContext.getActiveDialog().getState(), OPTIONS,
- QnAMakerDialogOptions.class);
+ QnAMakerDialogOptions dialogOptions =
+ ObjectPath.getPathValue(stepContext.getActiveDialog().getState(), OPTIONS, QnAMakerDialogOptions.class);
List trainResponses = (List) stepContext.getValues().get(ValueProperty.QNA_DATA);
String currentQuery = (String) stepContext.getValues().get(ValueProperty.CURRENT_QUERY);
String reply = stepContext.getContext().getActivity().getText();
if (trainResponses.size() > 1) {
- QueryResult qnaResult = trainResponses
- .stream().filter(kvp -> kvp.getQuestions()[0].equals(reply)).findFirst().orElse(null);
+ QueryResult qnaResult =
+ trainResponses.stream().filter(kvp -> kvp.getQuestions()[0].equals(reply)).findFirst().orElse(null);
if (qnaResult != null) {
List queryResultArr = new ArrayList();
stepContext.getValues().put(ValueProperty.QNA_DATA, queryResultArr.add(qnaResult));
- FeedbackRecord record = new FeedbackRecord() {{
- setUserId(stepContext.getContext().getActivity().getId());
- setUserQuestion(currentQuery);
- setQnaId(qnaResult.getId());
- }};
+ FeedbackRecord record = new FeedbackRecord() {
+ {
+ setUserId(stepContext.getContext().getActivity().getId());
+ setUserQuestion(currentQuery);
+ setQnaId(qnaResult.getId());
+ }
+ };
FeedbackRecord[] records = {record};
- FeedbackRecords feedbackRecords = new FeedbackRecords() {{
- setRecords(records);
- }};
+ FeedbackRecords feedbackRecords = new FeedbackRecords() {
+ {
+ setRecords(records);
+ }
+ };
// Call Active Learning Train API
return this.getQnAMakerClient(stepContext).thenCompose(qnaClient -> {
try {
- return qnaClient.callTrain(feedbackRecords).thenCompose(task ->
- stepContext.next(new ArrayList().add(qnaResult)));
+ return qnaClient.callTrain(feedbackRecords)
+ .thenCompose(task -> stepContext.next(new ArrayList().add(qnaResult)));
} catch (IOException e) {
LoggerFactory.getLogger(QnAMakerDialog.class).error("callTrain");
}
@@ -921,8 +963,8 @@ private CompletableFuture callTrain(WaterfallStepContext stepC
}
private CompletableFuture checkForMultiTurnPrompt(WaterfallStepContext stepContext) {
- QnAMakerDialogOptions dialogOptions = ObjectPath.getPathValue(stepContext.getActiveDialog().getState(),
- OPTIONS, QnAMakerDialogOptions.class);
+ QnAMakerDialogOptions dialogOptions =
+ ObjectPath.getPathValue(stepContext.getActiveDialog().getState(), OPTIONS, QnAMakerDialogOptions.class);
List response = (List) stepContext.getResult();
if (response != null && response.size() > 0) {
// -Check if context is present and prompt exists
@@ -936,21 +978,21 @@ private CompletableFuture checkForMultiTurnPrompt(WaterfallSte
QueryResult answer = response.get(0);
if (answer.getContext() != null && answer.getContext().getPrompts().length > 0) {
- Map previousContextData = ObjectPath.getPathValue(
- stepContext.getActiveDialog().getState(), QNA_CONTEXT_DATA, Map.class);
+ Map previousContextData =
+ ObjectPath.getPathValue(stepContext.getActiveDialog().getState(), QNA_CONTEXT_DATA, Map.class);
for (QnAMakerPrompt prompt : answer.getContext().getPrompts()) {
previousContextData.put(prompt.getDisplayText(), prompt.getQnaId());
}
- ObjectPath.setPathValue(stepContext.getActiveDialog().getState(),
- QNA_CONTEXT_DATA, previousContextData);
+ ObjectPath
+ .setPathValue(stepContext.getActiveDialog().getState(), QNA_CONTEXT_DATA, previousContextData);
ObjectPath.setPathValue(stepContext.getActiveDialog().getState(), PREVIOUS_QNA_ID, answer.getId());
ObjectPath.setPathValue(stepContext.getActiveDialog().getState(), OPTIONS, dialogOptions);
// Get multi-turn prompts card activity.
- Activity message = QnACardBuilder.getQnAPromptsCard(answer,
- dialogOptions.getResponseOptions().getCardNoMatchText());
+ Activity message =
+ QnACardBuilder.getQnAPromptsCard(answer, dialogOptions.getResponseOptions().getCardNoMatchText());
stepContext.getContext().sendActivity(message).join();
return CompletableFuture.completedFuture(new DialogTurnResult(DialogTurnStatus.WAITING));
@@ -967,6 +1009,7 @@ final class ValueProperty {
public static final String CURRENT_QUERY = "currentQuery";
public static final String QNA_DATA = "qnaData";
- private ValueProperty() { }
+ private ValueProperty() {
+ }
}
}
diff --git a/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/models/RankerTypes.java b/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/models/RankerTypes.java
index 0cd10e87e..da36cc393 100644
--- a/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/models/RankerTypes.java
+++ b/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/models/RankerTypes.java
@@ -22,5 +22,6 @@ public final class RankerTypes {
*/
public static final String AUTO_SUGGEST_QUESTION = "AutoSuggestQuestion";
- private RankerTypes() { }
+ private RankerTypes() {
+ }
}
diff --git a/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/utils/ActiveLearningUtils.java b/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/utils/ActiveLearningUtils.java
index 726f4cc6d..3275751fc 100644
--- a/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/utils/ActiveLearningUtils.java
+++ b/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/utils/ActiveLearningUtils.java
@@ -32,7 +32,8 @@ public final class ActiveLearningUtils {
private static Float minimumScoreForLowScoreVariation = MINIMUM_SCORE_VARIATION;
- private ActiveLearningUtils() { }
+ private ActiveLearningUtils() {
+ }
/**
* Gets maximum Score For Low Score Variation.
@@ -47,7 +48,7 @@ public static Float getMaximumScoreForLowScoreVariation() {
* Sets maximum Score For Low Score Variation.
*
* @param withMaximumScoreForLowScoreVariation Maximum Score For Low Score
- * Variation.
+ * Variation.
*/
public static void setMaximumScoreForLowScoreVariation(Float withMaximumScoreForLowScoreVariation) {
ActiveLearningUtils.maximumScoreForLowScoreVariation = withMaximumScoreForLowScoreVariation;
@@ -66,7 +67,7 @@ public static Float getMinimumScoreForLowScoreVariation() {
* Sets minimum Score For Low Score Variation.
*
* @param withMinimumScoreForLowScoreVariation Minimum Score For Low Score
- * Variation.
+ * Variation.
*/
public static void setMinimumScoreForLowScoreVariation(Float withMinimumScoreForLowScoreVariation) {
ActiveLearningUtils.minimumScoreForLowScoreVariation = withMinimumScoreForLowScoreVariation;
@@ -101,12 +102,17 @@ public static List getLowScoreVariation(List qnaSearch
filteredQnaSearchResult.add(qnaSearchResults.get(0));
for (int i = 1; i < qnaSearchResults.size(); i++) {
- if (ActiveLearningUtils
- .includeForClustering(prevScore, qnaSearchResults.get(i).getScore() * PERCENTAGE_DIVISOR,
- ActiveLearningUtils.PREVIOUS_LOW_SCORE_VARIATION_MULTIPLIER)
- && ActiveLearningUtils.includeForClustering(topAnswerScore,
- qnaSearchResults.get(i).getScore() * PERCENTAGE_DIVISOR,
- ActiveLearningUtils.MAX_LOW_SCORE_VARIATION_MULTIPLIER)) {
+ if (
+ ActiveLearningUtils.includeForClustering(
+ prevScore,
+ qnaSearchResults.get(i).getScore() * PERCENTAGE_DIVISOR,
+ ActiveLearningUtils.PREVIOUS_LOW_SCORE_VARIATION_MULTIPLIER
+ ) && ActiveLearningUtils.includeForClustering(
+ topAnswerScore,
+ qnaSearchResults.get(i).getScore() * PERCENTAGE_DIVISOR,
+ ActiveLearningUtils.MAX_LOW_SCORE_VARIATION_MULTIPLIER
+ )
+ ) {
prevScore = qnaSearchResults.get(i).getScore() * PERCENTAGE_DIVISOR;
filteredQnaSearchResult.add(qnaSearchResults.get(i));
}
diff --git a/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/utils/BindToActivity.java b/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/utils/BindToActivity.java
index 9126f0064..0262ba9bf 100644
--- a/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/utils/BindToActivity.java
+++ b/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/utils/BindToActivity.java
@@ -18,6 +18,7 @@ public class BindToActivity {
/**
* Construct to bind an Activity.
+ *
* @param withActivity activity to bind.
*/
public BindToActivity(Activity withActivity) {
@@ -27,7 +28,7 @@ public BindToActivity(Activity withActivity) {
/**
*
* @param context The context.
- * @param data The data.
+ * @param data The data.
* @return The activity.
*/
public CompletableFuture bind(DialogContext context, @Nullable Object data) {
@@ -36,6 +37,7 @@ public CompletableFuture bind(DialogContext context, @Nullable Object
/**
* Get the activity text.
+ *
* @return The activity text.
*/
public String toString() {
diff --git a/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/utils/GenerateAnswerUtils.java b/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/utils/GenerateAnswerUtils.java
index 05178903b..9436b7a7d 100644
--- a/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/utils/GenerateAnswerUtils.java
+++ b/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/utils/GenerateAnswerUtils.java
@@ -3,6 +3,7 @@
package com.microsoft.bot.ai.qna.utils;
+import com.microsoft.bot.connector.Async;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
@@ -39,11 +40,10 @@ public class GenerateAnswerUtils {
/**
* Initializes a new instance of the {@link GenerateAnswerUtils} class.
*
- * @param withEndpoint QnA Maker endpoint details.
- * @param withOptions QnA Maker options.
+ * @param withEndpoint QnA Maker endpoint details.
+ * @param withOptions QnA Maker options.
*/
- public GenerateAnswerUtils(QnAMakerEndpoint withEndpoint,
- QnAMakerOptions withOptions) {
+ public GenerateAnswerUtils(QnAMakerEndpoint withEndpoint, QnAMakerOptions withOptions) {
this.endpoint = withEndpoint;
this.options = withOptions != null ? withOptions : new QnAMakerOptions();
@@ -74,15 +74,18 @@ public void setOptions(QnAMakerOptions withOptions) {
* @param turnContext The Turn Context that contains the user question to be
* queried against your knowledge base.
* @param messageActivity Message activity of the turn context.
- * @param withOptions The options for the QnA Maker knowledge base. If null,
+ * @param withOptions The options for the QnA Maker knowledge base. If null,
* constructor option is used for this instance.
* @return A list of answers for the user query, sorted in decreasing order of
* ranking score.
* @throws IOException IOException
*/
@Deprecated
- public CompletableFuture getAnswers(TurnContext turnContext, Activity messageActivity,
- QnAMakerOptions withOptions) throws IOException {
+ public CompletableFuture getAnswers(
+ TurnContext turnContext,
+ Activity messageActivity,
+ QnAMakerOptions withOptions
+ ) throws IOException {
return this.getAnswersRaw(turnContext, messageActivity, withOptions).thenApply(result -> result.getAnswers());
}
@@ -92,24 +95,34 @@ public CompletableFuture getAnswers(TurnContext turnContext, Acti
* @param turnContext The Turn Context that contains the user question to be
* queried against your knowledge base.
* @param messageActivity Message activity of the turn context.
- * @param withOptions The options for the QnA Maker knowledge base. If null,
+ * @param withOptions The options for the QnA Maker knowledge base. If null,
* constructor option is used for this instance.
* @return A list of answers for the user query, sorted in decreasing order of
* ranking score.
*/
- public CompletableFuture getAnswersRaw(TurnContext turnContext, Activity messageActivity,
- QnAMakerOptions withOptions) {
+ public CompletableFuture getAnswersRaw(
+ TurnContext turnContext,
+ Activity messageActivity,
+ QnAMakerOptions withOptions
+ ) {
if (turnContext == null) {
- throw new IllegalArgumentException("turnContext");
+ return Async.completeExceptionally(new IllegalArgumentException("turnContext"));
}
if (turnContext.getActivity() == null) {
- throw new IllegalArgumentException(String.format("The %1$s property for %2$s can't be null: turnContext",
- turnContext.getActivity(), "turnContext"));
+ return Async.completeExceptionally(
+ new IllegalArgumentException(
+ String.format(
+ "The %1$s property for %2$s can't be null: turnContext",
+ turnContext.getActivity(),
+ "turnContext"
+ )
+ )
+ );
}
if (messageActivity == null) {
- throw new IllegalArgumentException("Activity type is not a message");
+ return Async.completeExceptionally(new IllegalArgumentException("Activity type is not a message"));
}
QnAMakerOptions hydratedOptions = this.hydrateOptions(withOptions);
@@ -126,8 +139,10 @@ public CompletableFuture getAnswersRaw(TurnContext turnContext, Ac
}
}
- private static CompletableFuture formatQnAResult(JsonNode response, QnAMakerOptions options)
- throws IOException {
+ private static CompletableFuture formatQnAResult(
+ JsonNode response,
+ QnAMakerOptions options
+ ) throws IOException {
String jsonResponse = null;
JacksonAdapter jacksonAdapter = new JacksonAdapter();
QueryResults results = null;
@@ -137,8 +152,10 @@ private static CompletableFuture formatQnAResult(JsonNode response
for (QueryResult answer : results.getAnswers()) {
answer.setScore(answer.getScore() / PERCENTAGE_DIVISOR);
}
- List answerList = Arrays.asList(results.getAnswers()).
- stream().filter(answer -> answer.getScore() > options.getScoreThreshold()).collect(Collectors.toList());
+ List answerList = Arrays.asList(results.getAnswers())
+ .stream()
+ .filter(answer -> answer.getScore() > options.getScoreThreshold())
+ .collect(Collectors.toList());
results.setAnswers(answerList.toArray(new QueryResult[answerList.size()]));
return CompletableFuture.completedFuture(results);
@@ -154,8 +171,9 @@ private static void validateOptions(QnAMakerOptions options) {
}
if (options.getScoreThreshold() < 0 || options.getScoreThreshold() > 1) {
- throw new IllegalArgumentException(String
- .format("options: The %s property should be a value between 0 and 1", options.getScoreThreshold()));
+ throw new IllegalArgumentException(
+ String.format("options: The %s property should be a value between 0 and 1", options.getScoreThreshold())
+ );
}
if (options.getTimeout() == 0.0d) {
@@ -187,15 +205,16 @@ private QnAMakerOptions hydrateOptions(QnAMakerOptions queryOptions) {
QnAMakerOptions hydratedOptions = null;
try {
- hydratedOptions = jacksonAdapter.deserialize(jacksonAdapter.serialize(options),
- QnAMakerOptions.class);
+ hydratedOptions = jacksonAdapter.deserialize(jacksonAdapter.serialize(options), QnAMakerOptions.class);
} catch (IOException e) {
LoggerFactory.getLogger(GenerateAnswerUtils.class).error("hydrateOptions");
}
if (queryOptions != null) {
- if (queryOptions.getScoreThreshold() != hydratedOptions.getScoreThreshold()
- && queryOptions.getScoreThreshold() != 0) {
+ if (
+ queryOptions.getScoreThreshold() != hydratedOptions.getScoreThreshold()
+ && queryOptions.getScoreThreshold() != 0
+ ) {
hydratedOptions.setScoreThreshold(queryOptions.getScoreThreshold());
}
@@ -210,18 +229,24 @@ private QnAMakerOptions hydrateOptions(QnAMakerOptions queryOptions) {
hydratedOptions.setContext(queryOptions.getContext());
hydratedOptions.setQnAId(queryOptions.getQnAId());
hydratedOptions.setIsTest(queryOptions.getIsTest());
- hydratedOptions.setRankerType(queryOptions.getRankerType() != null ? queryOptions.getRankerType()
- : RankerTypes.DEFAULT_RANKER_TYPE);
+ hydratedOptions.setRankerType(
+ queryOptions.getRankerType() != null ? queryOptions.getRankerType() : RankerTypes.DEFAULT_RANKER_TYPE
+ );
hydratedOptions.setStrictFiltersJoinOperator(queryOptions.getStrictFiltersJoinOperator());
}
return hydratedOptions;
}
- private CompletableFuture queryQnaService(Activity messageActivity, QnAMakerOptions withOptions)
- throws IOException {
- String requestUrl = String.format("%1$s/knowledgebases/%2$s/generateanswer", this.endpoint.getHost(),
- this.endpoint.getKnowledgeBaseId());
+ private CompletableFuture queryQnaService(
+ Activity messageActivity,
+ QnAMakerOptions withOptions
+ ) throws IOException {
+ String requestUrl = String.format(
+ "%1$s/knowledgebases/%2$s/generateanswer",
+ this.endpoint.getHost(),
+ this.endpoint.getKnowledgeBaseId()
+ );
JacksonAdapter jacksonAdapter = new JacksonAdapter();
String jsonRequest = null;
@@ -250,8 +275,12 @@ private CompletableFuture queryQnaService(Activity messageActivity
});
}
- private CompletableFuture emitTraceInfo(TurnContext turnContext, Activity messageActivity,
- QueryResult[] result, QnAMakerOptions withOptions) {
+ private CompletableFuture emitTraceInfo(
+ TurnContext turnContext,
+ Activity messageActivity,
+ QueryResult[] result,
+ QnAMakerOptions withOptions
+ ) {
String knowledgeBaseId = this.endpoint.getKnowledgeBaseId();
QnAMakerTraceInfo traceInfo = new QnAMakerTraceInfo() {
{
@@ -267,8 +296,12 @@ private CompletableFuture emitTraceInfo(TurnContext turnContext, Activity
setRankerType(withOptions.getRankerType());
}
};
- Activity traceActivity = Activity.createTraceActivity(QnAMaker.QNA_MAKER_NAME, QnAMaker.QNA_MAKER_TRACE_TYPE,
- traceInfo, QnAMaker.QNA_MAKER_TRACE_LABEL);
+ Activity traceActivity = Activity.createTraceActivity(
+ QnAMaker.QNA_MAKER_NAME,
+ QnAMaker.QNA_MAKER_TRACE_TYPE,
+ traceInfo,
+ QnAMaker.QNA_MAKER_TRACE_LABEL
+ );
return turnContext.sendActivity(traceActivity).thenApply(response -> null);
}
}
diff --git a/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/utils/HttpRequestUtils.java b/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/utils/HttpRequestUtils.java
index dcfff3e59..5e60838c4 100644
--- a/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/utils/HttpRequestUtils.java
+++ b/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/utils/HttpRequestUtils.java
@@ -3,8 +3,8 @@
package com.microsoft.bot.ai.qna.utils;
+import com.microsoft.bot.connector.Async;
import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.CompletionException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
@@ -25,6 +25,7 @@
*/
public class HttpRequestUtils {
private OkHttpClient httpClient = new OkHttpClient();
+
/**
* Execute Http request.
*
@@ -33,18 +34,23 @@ public class HttpRequestUtils {
* @param endpoint QnA Maker endpoint details.
* @return Returns http response object.
*/
- public CompletableFuture executeHttpRequest(String requestUrl, String payloadBody,
- QnAMakerEndpoint endpoint) {
+ public CompletableFuture executeHttpRequest(
+ String requestUrl,
+ String payloadBody,
+ QnAMakerEndpoint endpoint
+ ) {
if (requestUrl == null) {
- throw new IllegalArgumentException("requestUrl: Request url can not be null.");
+ return Async
+ .completeExceptionally(new IllegalArgumentException("requestUrl: Request url can not be null."));
}
if (payloadBody == null) {
- throw new IllegalArgumentException("payloadBody: Payload body can not be null.");
+ return Async
+ .completeExceptionally(new IllegalArgumentException("payloadBody: Payload body can not be null."));
}
if (endpoint == null) {
- throw new IllegalArgumentException("endpoint");
+ return Async.completeExceptionally(new IllegalArgumentException("endpoint"));
}
ObjectMapper mapper = new ObjectMapper();
@@ -57,11 +63,11 @@ public CompletableFuture executeHttpRequest(String requestUrl, String
qnaResponse = mapper.readTree(response.body().string());
if (!response.isSuccessful()) {
String message = "Unexpected code " + response.code();
- throw new Exception(message);
+ return Async.completeExceptionally(new Exception(message));
}
} catch (Exception e) {
LoggerFactory.getLogger(HttpRequestUtils.class).error("findPackages", e);
- throw new CompletionException(e);
+ return Async.completeExceptionally(e);
}
return CompletableFuture.completedFuture(qnaResponse);
@@ -69,15 +75,15 @@ public CompletableFuture executeHttpRequest(String requestUrl, String
private Request buildRequest(String requestUrl, String endpointKey, RequestBody body) {
HttpUrl.Builder httpBuilder = HttpUrl.parse(requestUrl).newBuilder();
- Request.Builder requestBuilder = new Request.Builder()
- .url(httpBuilder.build())
+ Request.Builder requestBuilder = new Request.Builder().url(httpBuilder.build())
.addHeader("Authorization", String.format("EndpointKey %s", endpointKey))
- .addHeader("Ocp-Apim-Subscription-Key", endpointKey).addHeader("User-Agent", UserAgent.value())
+ .addHeader("Ocp-Apim-Subscription-Key", endpointKey)
+ .addHeader("User-Agent", UserAgent.value())
.post(body);
return requestBuilder.build();
}
private RequestBody buildRequestBody(String payloadBody) throws JsonProcessingException {
- return RequestBody.create(payloadBody, MediaType.parse("application/json; charset=utf-8"));
+ return RequestBody.create(MediaType.parse("application/json; charset=utf-8"), payloadBody);
}
}
diff --git a/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/utils/QnACardBuilder.java b/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/utils/QnACardBuilder.java
index c2b7bb110..5f339ca02 100644
--- a/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/utils/QnACardBuilder.java
+++ b/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/utils/QnACardBuilder.java
@@ -19,7 +19,8 @@
*/
public final class QnACardBuilder {
- private QnACardBuilder() { }
+ private QnACardBuilder() {
+ }
/**
* Get active learning suggestions card.
diff --git a/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/utils/QnATelemetryConstants.java b/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/utils/QnATelemetryConstants.java
index 0fad35865..9827f6bd9 100644
--- a/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/utils/QnATelemetryConstants.java
+++ b/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/utils/QnATelemetryConstants.java
@@ -8,7 +8,8 @@
*/
public final class QnATelemetryConstants {
- private QnATelemetryConstants() { }
+ private QnATelemetryConstants() {
+ }
/**
* The Key used for the custom event type within telemetry.
diff --git a/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/utils/TrainUtils.java b/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/utils/TrainUtils.java
index d7fa020cc..3bdb9a086 100644
--- a/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/utils/TrainUtils.java
+++ b/libraries/bot-ai-qna/src/main/java/com/microsoft/bot/ai/qna/utils/TrainUtils.java
@@ -5,6 +5,7 @@
import com.microsoft.bot.ai.qna.QnAMakerEndpoint;
import com.microsoft.bot.ai.qna.models.FeedbackRecords;
+import com.microsoft.bot.connector.Async;
import com.microsoft.bot.restclient.serializer.JacksonAdapter;
import java.io.IOException;
@@ -34,7 +35,9 @@ public TrainUtils(QnAMakerEndpoint withEndpoint) {
*/
public CompletableFuture callTrain(FeedbackRecords feedbackRecords) throws IOException {
if (feedbackRecords == null) {
- throw new IllegalArgumentException("feedbackRecords: Feedback records cannot be null.");
+ return Async.completeExceptionally(
+ new IllegalArgumentException("feedbackRecords: Feedback records cannot be null.")
+ );
}
if (feedbackRecords.getRecords() == null || feedbackRecords.getRecords().length == 0) {
@@ -46,8 +49,8 @@ public CompletableFuture callTrain(FeedbackRecords feedbackRecords) throws
}
private CompletableFuture queryTrain(FeedbackRecords feedbackRecords) throws IOException {
- String requestUrl = String.format("%1$s/knowledgebases/%2$s/train", this.endpoint.getHost(),
- this.endpoint.getKnowledgeBaseId());
+ String requestUrl = String
+ .format("%1$s/knowledgebases/%2$s/train", this.endpoint.getHost(), this.endpoint.getKnowledgeBaseId());
JacksonAdapter jacksonAdapter = new JacksonAdapter();
String jsonRequest = jacksonAdapter.serialize(feedbackRecords);
diff --git a/libraries/bot-ai-qna/src/test/java/com/microsoft/bot/ai/qna/QnAMakerRecognizerTests.java b/libraries/bot-ai-qna/src/test/java/com/microsoft/bot/ai/qna/QnAMakerRecognizerTests.java
index cdb2f31d4..7443b01f2 100644
--- a/libraries/bot-ai-qna/src/test/java/com/microsoft/bot/ai/qna/QnAMakerRecognizerTests.java
+++ b/libraries/bot-ai-qna/src/test/java/com/microsoft/bot/ai/qna/QnAMakerRecognizerTests.java
@@ -98,6 +98,7 @@ public void noAnswer() {
Assert.assertEquals(result.getIntents().get("QnAMatch"), null);
Assert.assertNotEquals(result.getIntents().get("None"), null);
} catch (Exception e) {
+ e.printStackTrace();
fail();
} finally {
try {
diff --git a/libraries/bot-ai-qna/src/test/java/com/microsoft/bot/ai/qna/QnAMakerTests.java b/libraries/bot-ai-qna/src/test/java/com/microsoft/bot/ai/qna/QnAMakerTests.java
index 160b8ce78..253908994 100644
--- a/libraries/bot-ai-qna/src/test/java/com/microsoft/bot/ai/qna/QnAMakerTests.java
+++ b/libraries/bot-ai-qna/src/test/java/com/microsoft/bot/ai/qna/QnAMakerTests.java
@@ -197,7 +197,7 @@ public void qnaMakerTraceActivityEmptyText() {
}
};
TurnContext context = new TurnContextImpl(adapter, activity);
- Assert.assertThrows(IllegalArgumentException.class, () -> qna.getAnswers(context, null));
+ Assert.assertThrows(CompletionException.class, () -> qna.getAnswers(context, null).join());
} catch (Exception e) {
fail();
} finally {
@@ -229,7 +229,7 @@ public void qnaMakerTraceActivityNullText() {
}
};
TurnContext context = new TurnContextImpl(adapter, activity);
- Assert.assertThrows(IllegalArgumentException.class, () -> qna.getAnswers(context, null));
+ Assert.assertThrows(CompletionException.class, () -> qna.getAnswers(context, null).join());
} catch (Exception e) {
fail();
} finally {
@@ -248,7 +248,7 @@ public void qnaMakerTraceActivityNullContext() {
// Get basic Qna
QnAMaker qna = this.qnaReturnsAnswer(mockWebServer);
- Assert.assertThrows(IllegalArgumentException.class, () -> qna.getAnswers(null, null));
+ Assert.assertThrows(CompletionException.class, () -> qna.getAnswers(null, null).join());
} catch (Exception e) {
fail();
} finally {
@@ -281,7 +281,7 @@ public void qnaMakerTraceActivityBadMessage() {
};
TurnContext context = new TurnContextImpl(adapter, activity);
- Assert.assertThrows(IllegalArgumentException.class, () -> qna.getAnswers(context, null));
+ Assert.assertThrows(CompletionException.class, () -> qna.getAnswers(context, null).join());
} catch (Exception e) {
fail();
} finally {
@@ -304,7 +304,7 @@ public void qnaMakerTraceActivityNullActivity() {
TestAdapter adapter = new TestAdapter(
TestAdapter.createConversationReference("QnaMaker_TraceActivity_NullActivity", "User1", "Bot"));
TurnContext context = new MyTurnContext(adapter, null);
- Assert.assertThrows(IllegalArgumentException.class, () -> qna.getAnswers(context, null));
+ Assert.assertThrows(CompletionException.class, () -> qna.getAnswers(context, null).join());
} catch (Exception e) {
fail();
} finally {
@@ -1076,7 +1076,7 @@ public void qnaMakerTestUnsuccessfulResponse() {
}
};
QnAMaker qna = new QnAMaker(qnAMakerEndpoint, null);
- Assert.assertThrows(CompletionException.class, () -> qna.getAnswers(getContext("how do I clean the stove?"), null));
+ Assert.assertThrows(CompletionException.class, () -> qna.getAnswers(getContext("how do I clean the stove?"), null).join());
} catch (Exception e) {
fail();
} finally {
diff --git a/libraries/bot-connector/pom.xml b/libraries/bot-connector/pom.xml
index 0e04806b7..f892898cd 100644
--- a/libraries/bot-connector/pom.xml
+++ b/libraries/bot-connector/pom.xml
@@ -60,31 +60,31 @@
guava
30.1-jre
+
com.squareup.retrofit2
retrofit
2.5.0
+
+ com.squareup.retrofit2
+ converter-jackson
+ 2.5.0
+
+
com.squareup.okhttp3
okhttp
- 3.12.2
com.squareup.okhttp3
logging-interceptor
- 3.12.2
com.squareup.okhttp3
okhttp-urlconnection
- 3.12.2
-
-
- com.squareup.retrofit2
- converter-jackson
- 2.5.0
+
com.microsoft.azure
azure-annotations
diff --git a/pom.xml b/pom.xml
index c2a9d09df..40936bc97 100644
--- a/pom.xml
+++ b/pom.xml
@@ -311,6 +311,28 @@
test
+
+ com.squareup.okhttp3
+ okhttp
+ 3.12.2
+
+
+ com.squareup.okhttp3
+ logging-interceptor
+ 3.12.2
+
+
+ com.squareup.okhttp3
+ okhttp-urlconnection
+ 3.12.2
+
+
+ com.squareup.okhttp3
+ mockwebserver
+ 3.12.2
+ test
+
+
com.microsoft.bot
bot-schema