Luis-v3, switched to JUnit 4 to get Maven unit tests running, code formatting (#1017)

This commit is contained in:
tracyboehrer 2021-02-23 16:08:10 -06:00 коммит произвёл GitHub
Родитель de1867d1a2
Коммит 94e5eef926
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
15 изменённых файлов: 710 добавлений и 700 удалений

Просмотреть файл

@ -48,6 +48,12 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
@ -69,31 +75,17 @@
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.9.0</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>mockwebserver</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20190722</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>mockwebserver</artifactId>
<version>4.9.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>5.7.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>3.6.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<profiles>

Просмотреть файл

@ -7,7 +7,8 @@ import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
/**
* Request Body element to use when passing Dynamic lists to the Luis Service call.
* Request Body element to use when passing Dynamic lists to the Luis Service
* call.
*
*/
public class DynamicList {
@ -20,7 +21,8 @@ public class DynamicList {
/**
* Initializes a new instance of the DynamicList class.
* @param entity Entity field.
*
* @param entity Entity field.
* @param requestLists List Elements to use when querying Luis Service.
*/
public DynamicList(String entity, List<ListElement> requestLists) {
@ -36,6 +38,7 @@ public class DynamicList {
/**
* Gets the entity.
*
* @return Entity name.
*/
public String getEntity() {
@ -44,6 +47,7 @@ public class DynamicList {
/**
* Sets the entity name.
*
* @param entity entity name.
*/
public void setEntity(String entity) {
@ -52,6 +56,7 @@ public class DynamicList {
/**
* Gets the List.
*
* @return Element list of the Dynamic List.
*/
public List<ListElement> getList() {
@ -60,6 +65,7 @@ public class DynamicList {
/**
* Sets the List.
*
* @param list Element list of the Dynamic List.
*/
public void setList(List<ListElement> list) {
@ -68,6 +74,7 @@ public class DynamicList {
/**
* Validate the object.
*
* @throws IllegalArgumentException on null or invalid values.
*/
public void validate() throws IllegalArgumentException {
@ -76,7 +83,7 @@ public class DynamicList {
throw new IllegalArgumentException("ExternalEntity requires an EntityName and EntityLength > 0");
}
for (ListElement e: list) {
for (ListElement e : list) {
e.validate();
}
}

Просмотреть файл

@ -7,7 +7,8 @@ import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.JsonNode;
/**
* Request Body element to use when passing External Entities to the Luis Service call.
* Request Body element to use when passing External Entities to the Luis
* Service call.
*
*/
public class ExternalEntity {
@ -20,10 +21,12 @@ public class ExternalEntity {
/**
* Initializes a new instance of ExternalEntity.
* @param entity name of the entity to extend.
* @param start start character index of the predicted entity.
* @param length length of the predicted entity.
* @param resolution supplied custom resolution to return as the entity's prediction.
*
* @param entity name of the entity to extend.
* @param start start character index of the predicted entity.
* @param length length of the predicted entity.
* @param resolution supplied custom resolution to return as the entity's
* prediction.
*/
public ExternalEntity(String entity, int start, int length, JsonNode resolution) {
this.entity = entity;
@ -35,11 +38,9 @@ public class ExternalEntity {
@JsonProperty(value = "entityName")
private String entity;
@JsonProperty(value = "startIndex")
private int start;
@JsonProperty(value = "entityLength")
private int length = -1;
@ -48,6 +49,7 @@ public class ExternalEntity {
/**
* Gets the start character index of the predicted entity.
*
* @return start character index of the predicted entity.
*/
public int getStart() {
@ -56,6 +58,7 @@ public class ExternalEntity {
/**
* Sets the start character index of the predicted entity.
*
* @param start character index of the predicted entity.
*/
public void setStart(int start) {
@ -64,6 +67,7 @@ public class ExternalEntity {
/**
* Gets the name of the entity to extend.
*
* @return name of the entity to extend.
*/
public String getEntity() {
@ -72,6 +76,7 @@ public class ExternalEntity {
/**
* Sets the name of the entity to extend.
*
* @param entity name of the entity to extend.
*/
public void setEntity(String entity) {
@ -80,6 +85,7 @@ public class ExternalEntity {
/**
* Gets the length of the predicted entity.
*
* @return length of the predicted entity.
*/
public int getLength() {
@ -88,6 +94,7 @@ public class ExternalEntity {
/**
* Sets the length of the predicted entity.
*
* @param length of the predicted entity.
*/
public void setLength(int length) {
@ -96,6 +103,7 @@ public class ExternalEntity {
/**
* Gets a user supplied custom resolution to return as the entity's prediction.
*
* @return custom resolution to return as the entity's prediction.
*/
public JsonNode getResolution() {
@ -104,6 +112,7 @@ public class ExternalEntity {
/**
* Sets External entities to be recognized in query.
*
* @param resolution custom resolution to return as the entity's prediction.
*/
public void setResolution(JsonNode resolution) {
@ -112,6 +121,7 @@ public class ExternalEntity {
/**
* Validate the object.
*
* @throws IllegalArgumentException on null or invalid values
*/
public void validate() throws IllegalArgumentException {

Просмотреть файл

@ -22,8 +22,9 @@ public class ListElement {
/**
* Initializes a new instance of the ListElement class.
*
* @param canonicalForm The canonical form of the sub-list.
* @param synonyms The synonyms of the canonical form.
* @param synonyms The synonyms of the canonical form.
*/
public ListElement(String canonicalForm, List<String> synonyms) {
this.canonicalForm = canonicalForm;
@ -45,6 +46,7 @@ public class ListElement {
/**
* Gets the canonical form of the sub-list.
*
* @return String canonical form of the sub-list.
*/
public String getCanonicalForm() {
@ -53,6 +55,7 @@ public class ListElement {
/**
* Sets the canonical form of the sub-list.
*
* @param canonicalForm the canonical form of the sub-list.
*/
public void setCanonicalForm(String canonicalForm) {
@ -61,6 +64,7 @@ public class ListElement {
/**
* Gets the synonyms of the canonical form.
*
* @return the synonyms List of the canonical form.
*/
public List<String> getSynonyms() {
@ -69,6 +73,7 @@ public class ListElement {
/**
* Sets the synonyms of the canonical form.
*
* @param synonyms List of synonyms of the canonical form.
*/
public void setSynonyms(List<String> synonyms) {
@ -77,6 +82,7 @@ public class ListElement {
/**
* Validate the object.
*
* @throws IllegalArgumentException if canonicalForm is null.
*/
public void validate() throws IllegalArgumentException {

Просмотреть файл

@ -11,7 +11,8 @@ import java.net.URL;
import java.util.UUID;
/**
* Luis Application representation with information necessary to query the specific Luis Application.
* Luis Application representation with information necessary to query the
* specific Luis Application.
*
*/
public class LuisApplication {
@ -32,39 +33,37 @@ public class LuisApplication {
private String endpoint;
/**
* Luis endpoint like https://westus.api.cognitive.microsoft.com.
* Luis endpoint like https://westus.api.cognitive.microsoft.com.
*/
public LuisApplication() {
}
/**
* Initializes a new instance of the Luis Application class.
*
* @param applicationId Luis Application ID to query
* @param endpointKey LUIS subscription or endpoint key.
* @param endpoint LUIS endpoint to use like https://westus.api.cognitive.microsoft.com
* @param endpointKey LUIS subscription or endpoint key.
* @param endpoint LUIS endpoint to use like
* https://westus.api.cognitive.microsoft.com
*/
public LuisApplication(
String applicationId,
String endpointKey,
String endpoint) {
setLuisApplication(
applicationId,
endpointKey,
endpoint);
public LuisApplication(String applicationId, String endpointKey, String endpoint) {
setLuisApplication(applicationId, endpointKey, endpoint);
}
/**
* Initializes a new instance of the Luis Application class.
* @param applicationEndpoint LUIS application query endpoint containing subscription key
* and application id as part of the url.
*
* @param applicationEndpoint LUIS application query endpoint containing
* subscription key and application id as part of the
* url.
*/
public LuisApplication(
String applicationEndpoint) {
public LuisApplication(String applicationEndpoint) {
parse(applicationEndpoint);
}
/**
* Sets Luis application ID to query.
*
* @param applicationId Luis application ID to query.
*/
public void setApplicationId(String applicationId) {
@ -73,6 +72,7 @@ public class LuisApplication {
/**
* Gets Luis application ID.
*
* @return applicationId.
*/
public String getApplicationId() {
@ -81,6 +81,7 @@ public class LuisApplication {
/**
* Sets the LUIS subscription or endpoint key.
*
* @param endpointKey LUIS subscription or endpoint key.
*/
public void setEndpointKey(String endpointKey) {
@ -89,6 +90,7 @@ public class LuisApplication {
/**
* Gets the LUIS subscription or endpoint key.
*
* @return endpointKey.
*/
public String getEndpointKey() {
@ -97,6 +99,7 @@ public class LuisApplication {
/**
* Sets Luis endpoint like https://westus.api.cognitive.microsoft.com.
*
* @param endpoint endpoint like https://westus.api.cognitive.microsoft.com.
*/
public void setEndpoint(String endpoint) {
@ -105,6 +108,7 @@ public class LuisApplication {
/**
* Gets the LUIS endpoint where application is hosted.
*
* @return endpoint.
*/
public String getEndpoint() {
@ -114,16 +118,12 @@ public class LuisApplication {
/**
* Helper method to set and validate Luis arguments passed.
*/
private void setLuisApplication(
String applicationId,
String endpointKey,
String endpoint) {
private void setLuisApplication(String applicationId, String endpointKey, String endpoint) {
if (!isValidUUID(applicationId)) {
throw new IllegalArgumentException(String.format("%s is not a valid LUIS application id.", applicationId));
}
if (!isValidUUID(endpointKey)) {
throw new IllegalArgumentException(String.format("%s is not a valid LUIS subscription key.", endpointKey));
}
@ -142,14 +142,13 @@ public class LuisApplication {
}
/**
* Helper method to parse validate and set Luis application members from the full application full endpoint.
* Helper method to parse validate and set Luis application members from the
* full application full endpoint.
*/
private void parse(String applicationEndpoint) {
String appId = "";
try {
String[] segments = new URL(applicationEndpoint)
.getPath()
.split("/");
String[] segments = new URL(applicationEndpoint).getPath().split("/");
for (int segment = 0; segment < segments.length - 1; segment++) {
if (segments[segment].equals("apps")) {
appId = segments[segment + 1].trim();
@ -158,30 +157,21 @@ public class LuisApplication {
}
} catch (MalformedURLException e) {
throw new IllegalArgumentException(
String.format(
"Unable to create the LUIS endpoint with the given %s.",
applicationEndpoint
)
String.format("Unable to create the LUIS endpoint with the given %s.", applicationEndpoint)
);
}
if (appId.isEmpty()) {
throw new IllegalArgumentException(
String.format(
"Could not find application Id in %s",
applicationEndpoint
)
String.format("Could not find application Id in %s", applicationEndpoint)
);
}
try {
String endpointKeyParsed = new URIBuilder(applicationEndpoint)
.getQueryParams()
String endpointKeyParsed = new URIBuilder(applicationEndpoint).getQueryParams()
.stream()
.filter(param -> param.getName()
.equalsIgnoreCase("subscription-key"))
.filter(param -> param.getName().equalsIgnoreCase("subscription-key"))
.map(NameValuePair::getValue)
.findFirst()
.orElse("");
@ -195,10 +185,8 @@ public class LuisApplication {
setLuisApplication(appId, endpointKeyParsed, endpointPared);
} catch (URISyntaxException | MalformedURLException e) {
throw new IllegalArgumentException(
String.format(
"Unable to create the LUIS endpoint with the given %s.",
applicationEndpoint
));
String.format("Unable to create the LUIS endpoint with the given %s.", applicationEndpoint)
);
}
}
@ -206,10 +194,7 @@ public class LuisApplication {
private boolean isValidUUID(String uuid) {
try {
if (!uuid.contains("-")) {
uuid = uuid.replaceAll(
"(.{8})(.{4})(.{4})(.{4})(.+)",
"$1-$2-$3-$4-$5"
);
uuid = uuid.replaceAll("(.{8})(.{4})(.{4})(.{4})(.+)", "$1-$2-$3-$4-$5");
}
return UUID.fromString(uuid).toString().equals(uuid);

Просмотреть файл

@ -21,18 +21,21 @@ import java.util.Map;
import java.util.concurrent.CompletableFuture;
/**
* Luis Recognizer class to query the LUIS Service using the configuration set by the LuisRecognizeroptions.
* Luis Recognizer class to query the LUIS Service using the configuration set
* by the LuisRecognizeroptions.
*
*/
public class LuisRecognizer extends TelemetryRecognizer {
/**
* Luis Recognizer options to query the Luis Service.
*/
private LuisRecognizerOptions luisRecognizerOptions;
private LuisRecognizerOptions luisRecognizerOptions;
/**
* Initializes a new instance of the Luis Recognizer .
* @param recognizerOptions Luis Recognizer options to use when calling th LUIS Service.
*
* @param recognizerOptions Luis Recognizer options to use when calling th LUIS
* Service.
* @throws IllegalArgumentException if null is passed as recognizerOptions.
*/
public LuisRecognizer(LuisRecognizerOptions recognizerOptions) {
@ -42,58 +45,60 @@ public class LuisRecognizer extends TelemetryRecognizer {
this.luisRecognizerOptions = recognizerOptions;
this.setLogPersonalInformation(recognizerOptions.isLogPersonalInformation());
this.setTelemetryClient(recognizerOptions.getTelemetryClient() != null
? recognizerOptions.getTelemetryClient()
: new NullBotTelemetryClient());
this.setTelemetryClient(
recognizerOptions.getTelemetryClient() != null
? recognizerOptions.getTelemetryClient()
: new NullBotTelemetryClient()
);
}
/**
* Returns the name of the top scoring intent from a set of LUIS results.
*
* @param results The Recognizer Result with the list of Intents to filter.
* Defaults to a value of "None" and a min score value of `0.0`
* Defaults to a value of "None" and a min score value of `0.0`
* @return The top scoring intent name.
*/
public static String topIntent(
RecognizerResult results) {
public static String topIntent(RecognizerResult results) {
return topIntent(results, "None");
}
/**
* Returns the name of the top scoring intent from a set of LUIS results.
*
* @param results The Recognizer Result with the list of Intents to filter
* @param defaultIntent Intent name to return should a top intent be found.
* Defaults to a value of "None" and a min score value of `0.0`
* Defaults to a value of "None" and a min score value of
* `0.0`
* @return The top scoring intent name.
*/
public static String topIntent(
RecognizerResult results,
String defaultIntent) {
public static String topIntent(RecognizerResult results, String defaultIntent) {
return topIntent(results, defaultIntent, 0.0);
}
/**
* Returns the name of the top scoring intent from a set of LUIS results.
* @param results The Recognizer Result with the list of Intents to filter.
* @param minScore Minimum score needed for an intent to be considered as a top intent.
*
* @param results The Recognizer Result with the list of Intents to filter.
* @param minScore Minimum score needed for an intent to be considered as a top
* intent.
* @return The top scoring intent name.
*/
public static String topIntent(
RecognizerResult results,
double minScore) {
public static String topIntent(RecognizerResult results, double minScore) {
return topIntent(results, "None", minScore);
}
/**
* Returns the name of the top scoring intent from a set of LUIS results.
*
* @param results The Recognizer Result with the list of Intents to filter
* @param defaultIntent Intent name to return should a top intent be found. Defaults to a value of "None
* @param minScore Minimum score needed for an intent to be considered as a top intent.
* @param defaultIntent Intent name to return should a top intent be found.
* Defaults to a value of "None
* @param minScore Minimum score needed for an intent to be considered as a
* top intent.
* @return The top scoring intent name.
*/
public static String topIntent(
RecognizerResult results,
String defaultIntent,
double minScore) {
public static String topIntent(RecognizerResult results, String defaultIntent, double minScore) {
if (results == null) {
throw new IllegalArgumentException("RecognizerResult");
}
@ -118,325 +123,353 @@ public class LuisRecognizer extends TelemetryRecognizer {
/**
* Return results of the analysis (Suggested actions and intents).
* @param turnContext Context object containing information for a single turn of conversation with a user.
* @return The LUIS results of the analysis of the current message text in the current turn's context activity.
*
* @param turnContext Context object containing information for a single turn of
* conversation with a user.
* @return The LUIS results of the analysis of the current message text in the
* current turn's context activity.
*/
@Override
public CompletableFuture<RecognizerResult> recognize(
TurnContext turnContext) {
return recognizeInternal(
turnContext,
null,
null,
null);
public CompletableFuture<RecognizerResult> recognize(TurnContext turnContext) {
return recognizeInternal(turnContext, null, null, null);
}
/**
* Return results of the analysis (Suggested actions and intents).
* @param dialogContext Context object containing information for a single turn of conversation with a user.
*
* @param dialogContext Context object containing information for a single turn
* of conversation with a user.
* @param activity Activity to recognize.
* @return The LUIS results of the analysis of the current message text in the current turn's context activity.
* @return The LUIS results of the analysis of the current message text in the
* current turn's context activity.
*/
public CompletableFuture<RecognizerResult> recognize(
DialogContext dialogContext,
Activity activity) {
return recognizeInternal(
dialogContext,
activity,
null,
null,
null);
public CompletableFuture<RecognizerResult> recognize(DialogContext dialogContext, Activity activity) {
return recognizeInternal(dialogContext, activity, null, null, null);
}
/**
* Runs an utterance through a recognizer and returns a strongly-typed recognizer result.
* @param turnContext Context object containing information for a single turn of conversation with a user.
* @param <T> type of result.
* @param c RecognizerConvert implemented class to convert the Recognizer Result into.
* @return The LUIS results of the analysis of the current message text in the current turn's context activity.
* Runs an utterance through a recognizer and returns a strongly-typed
* recognizer result.
*
* @param turnContext Context object containing information for a single turn of
* conversation with a user.
* @param <T> type of result.
* @param c RecognizerConvert implemented class to convert the
* Recognizer Result into.
* @return The LUIS results of the analysis of the current message text in the
* current turn's context activity.
*/
public <T extends RecognizerConvert> CompletableFuture<T> recognize(
TurnContext turnContext,
Class<T> c) {
return recognizeInternal(
turnContext,
null,
null,
null)
public <T extends RecognizerConvert> CompletableFuture<T> recognize(TurnContext turnContext, Class<T> c) {
return recognizeInternal(turnContext, null, null, null)
.thenApply(recognizerResult -> convertRecognizerResult(recognizerResult, c));
}
/**
* Runs an utterance through a recognizer and returns a strongly-typed recognizer result.
* @param dialogContext Context object containing information for a single turn of conversation with a user.
* Runs an utterance through a recognizer and returns a strongly-typed
* recognizer result.
*
* @param dialogContext Context object containing information for a single turn
* of conversation with a user.
* @param activity Activity to recognize.
* @param <T> Type of result.
* @param c RecognizerConvert implemented class to convert the Recognizer Result into.
* @return The LUIS results of the analysis of the current message text in the current turn's context activity.
* @param c RecognizerConvert implemented class to convert the
* Recognizer Result into.
* @return The LUIS results of the analysis of the current message text in the
* current turn's context activity.
*/
public <T extends RecognizerConvert> CompletableFuture<T> recognize(
DialogContext dialogContext,
Activity activity,
Class<T> c) {
return recognizeInternal(
dialogContext,
activity,
null,
null,
null)
Class<T> c
) {
return recognizeInternal(dialogContext, activity, null, null, null)
.thenApply(recognizerResult -> convertRecognizerResult(recognizerResult, c));
}
/**
* Return results of the analysis (Suggested actions and intents).
* @param turnContext Context object containing information for a single turn of conversation with a user.
* @param telemetryProperties Additional properties to be logged to telemetry with the LuisResult event.
* @param telemetryMetrics Additional metrics to be logged to telemetry with the LuisResult event.
* @return The LUIS results of the analysis of the current message text in the current turn's context activity.
*
* @param turnContext Context object containing information for a single
* turn of conversation with a user.
* @param telemetryProperties Additional properties to be logged to telemetry
* with the LuisResult event.
* @param telemetryMetrics Additional metrics to be logged to telemetry with
* the LuisResult event.
* @return The LUIS results of the analysis of the current message text in the
* current turn's context activity.
*/
@Override
public CompletableFuture<RecognizerResult> recognize(
TurnContext turnContext,
Map<String, String> telemetryProperties,
Map<String, Double> telemetryMetrics) {
return recognizeInternal(
turnContext,
null,
telemetryProperties,
telemetryMetrics);
Map<String, Double> telemetryMetrics
) {
return recognizeInternal(turnContext, null, telemetryProperties, telemetryMetrics);
}
/**
* Return results of the analysis (Suggested actions and intents).
* @param dialogContext Context object containing information for a single turn of conversation with a user.
*
* @param dialogContext Context object containing information for a single
* turn of conversation with a user.
* @param activity Activity to recognize.
* @param telemetryProperties Additional properties to be logged to telemetry with the LuisResult event.
* @param telemetryMetrics Additional metrics to be logged to telemetry with the LuisResult event.
* @return The LUIS results of the analysis of the current message text in the current turn's context activity.
* @param telemetryProperties Additional properties to be logged to telemetry
* with the LuisResult event.
* @param telemetryMetrics Additional metrics to be logged to telemetry with
* the LuisResult event.
* @return The LUIS results of the analysis of the current message text in the
* current turn's context activity.
*/
public CompletableFuture<RecognizerResult> recognize(
DialogContext dialogContext,
Activity activity,
Map<String, String> telemetryProperties,
Map<String, Double> telemetryMetrics) {
return recognizeInternal(
dialogContext,
activity,
null,
telemetryProperties,
telemetryMetrics);
Map<String, Double> telemetryMetrics
) {
return recognizeInternal(dialogContext, activity, null, telemetryProperties, telemetryMetrics);
}
/**
* Runs an utterance through a recognizer and returns a strongly-typed recognizer result.
* @param turnContext Context object containing information for a single turn of conversation with a user.
* @param telemetryProperties Additional properties to be logged to telemetry with the LuisResult event.
* @param telemetryMetrics Additional metrics to be logged to telemetry with the LuisResult event.
* Runs an utterance through a recognizer and returns a strongly-typed
* recognizer result.
*
* @param turnContext Context object containing information for a single
* turn of conversation with a user.
* @param telemetryProperties Additional properties to be logged to telemetry
* with the LuisResult event.
* @param telemetryMetrics Additional metrics to be logged to telemetry with
* the LuisResult event.
* @param <T> Type of result.
* @param c RecognizerConvert implemented class to convert the Recognizer Result into.
* @return The LUIS results of the analysis of the current message text in the current turn's context activity.
* @param c RecognizerConvert implemented class to convert the
* Recognizer Result into.
* @return The LUIS results of the analysis of the current message text in the
* current turn's context activity.
*/
public <T extends RecognizerConvert> CompletableFuture<T> recognize(
TurnContext turnContext,
Map<String, String> telemetryProperties,
Map<String, Double> telemetryMetrics,
Class<T> c) {
return recognizeInternal(
turnContext,
null,
telemetryProperties,
telemetryMetrics)
Class<T> c
) {
return recognizeInternal(turnContext, null, telemetryProperties, telemetryMetrics)
.thenApply(recognizerResult -> convertRecognizerResult(recognizerResult, c));
}
/**
* Runs an utterance through a recognizer and returns a strongly-typed recognizer result.
* @param dialogContext Context object containing information for a single turn of conversation with a user.
* Runs an utterance through a recognizer and returns a strongly-typed
* recognizer result.
*
* @param dialogContext Context object containing information for a single
* turn of conversation with a user.
* @param activity Activity to recognize.
* @param telemetryProperties Additional properties to be logged to telemetry with the LuisResult event.
* @param telemetryMetrics Additional metrics to be logged to telemetry with the LuisResult event.
* @param telemetryProperties Additional properties to be logged to telemetry
* with the LuisResult event.
* @param telemetryMetrics Additional metrics to be logged to telemetry with
* the LuisResult event.
* @param <T> Type of result.
* @param c RecognizerConvert implemented class to convert the Recognizer Result into.
* @return The LUIS results of the analysis of the current message text in the current turn's context activity.
* @param c RecognizerConvert implemented class to convert the
* Recognizer Result into.
* @return The LUIS results of the analysis of the current message text in the
* current turn's context activity.
*/
public <T extends RecognizerConvert> CompletableFuture<T> recognize(
DialogContext dialogContext,
Activity activity,
Map<String, String> telemetryProperties,
Map<String, Double> telemetryMetrics,
Class<T> c) {
return recognizeInternal(
dialogContext,
activity,
null,
telemetryProperties,
telemetryMetrics)
Class<T> c
) {
return recognizeInternal(dialogContext, activity, null, telemetryProperties, telemetryMetrics)
.thenApply(recognizerResult -> convertRecognizerResult(recognizerResult, c));
}
/**
* Return results of the analysis (Suggested actions and intents).
* @param turnContext Context object containing information for a single turn of conversation with a user.
* @param recognizerOptions A LuisRecognizerOptions instance to be used by the call. This parameter overrides the
* default LuisRecognizerOptions passed in the constructor.
* @return The LUIS results of the analysis of the current message text in the current turn's context activity.
*
* @param turnContext Context object containing information for a single
* turn of conversation with a user.
* @param recognizerOptions A LuisRecognizerOptions instance to be used by the
* call. This parameter overrides the default
* LuisRecognizerOptions passed in the constructor.
* @return The LUIS results of the analysis of the current message text in the
* current turn's context activity.
*/
public CompletableFuture<RecognizerResult> recognize(
TurnContext turnContext,
LuisRecognizerOptions recognizerOptions) {
return recognizeInternal(
turnContext,
recognizerOptions,
null,
null);
LuisRecognizerOptions recognizerOptions
) {
return recognizeInternal(turnContext, recognizerOptions, null, null);
}
/**
* Return results of the analysis (Suggested actions and intents).
* @param dialogContext Context object containing information for a single turn of conversation with a user.
*
* @param dialogContext Context object containing information for a single
* turn of conversation with a user.
* @param activity Activity to recognize.
* @param recognizerOptions A LuisRecognizerOptions instance to be used by the call. This parameter overrides the
* default LuisRecognizerOptions passed in the constructor.
* @return The LUIS results of the analysis of the current message text in the current turn's context activity.
* @param recognizerOptions A LuisRecognizerOptions instance to be used by the
* call. This parameter overrides the default
* LuisRecognizerOptions passed in the constructor.
* @return The LUIS results of the analysis of the current message text in the
* current turn's context activity.
*/
public CompletableFuture<RecognizerResult> recognize(
DialogContext dialogContext,
Activity activity,
LuisRecognizerOptions recognizerOptions) {
return recognizeInternal(
dialogContext,
activity,
recognizerOptions,
null,
null);
LuisRecognizerOptions recognizerOptions
) {
return recognizeInternal(dialogContext, activity, recognizerOptions, null, null);
}
/**
* Runs an utterance through a recognizer and returns a strongly-typed recognizer result.
* @param turnContext Context object containing information for a single turn of conversation with a user.
* @param recognizerOptions A LuisRecognizerOptions instance to be used by the call. This parameter overrides the
* default LuisRecognizerOptions passed in the constructor.
* Runs an utterance through a recognizer and returns a strongly-typed
* recognizer result.
*
* @param turnContext Context object containing information for a single
* turn of conversation with a user.
* @param recognizerOptions A LuisRecognizerOptions instance to be used by the
* call. This parameter overrides the default
* LuisRecognizerOptions passed in the constructor.
* @param <T> type of result.
* @param c RecognizerConvert implemented class to convert the Recognizer Result into.
* @return The LUIS results of the analysis of the current message text in the current turn's context activity.
* @param c RecognizerConvert implemented class to convert the
* Recognizer Result into.
* @return The LUIS results of the analysis of the current message text in the
* current turn's context activity.
*/
public <T extends RecognizerConvert> CompletableFuture<T> recognize(
TurnContext turnContext,
LuisRecognizerOptions recognizerOptions,
Class<T> c) {
return recognizeInternal(
turnContext,
recognizerOptions,
null,
null)
Class<T> c
) {
return recognizeInternal(turnContext, recognizerOptions, null, null)
.thenApply(recognizerResult -> convertRecognizerResult(recognizerResult, c));
}
/**
* Runs an utterance through a recognizer and returns a strongly-typed recognizer result.
* @param dialogContext Context object containing information for a single turn of conversation with a user.
* Runs an utterance through a recognizer and returns a strongly-typed
* recognizer result.
*
* @param dialogContext Context object containing information for a single
* turn of conversation with a user.
* @param activity Activity to recognize.
* @param recognizerOptions A LuisRecognizerOptions instance to be used by the call. This parameter overrides the
* default LuisRecognizerOptions passed in the constructor.
* @param recognizerOptions A LuisRecognizerOptions instance to be used by the
* call. This parameter overrides the default
* LuisRecognizerOptions passed in the constructor.
* @param <T> Type of result.
* @param c RecognizerConvert implemented class to convert the Recognizer Result into.
* @return The LUIS results of the analysis of the current message text in the current turn's context activity.
* @param c RecognizerConvert implemented class to convert the
* Recognizer Result into.
* @return The LUIS results of the analysis of the current message text in the
* current turn's context activity.
*/
public <T extends RecognizerConvert> CompletableFuture<T> recognize(
DialogContext dialogContext,
Activity activity,
LuisRecognizerOptions recognizerOptions,
Class<T> c) {
return recognizeInternal(
dialogContext,
activity,
recognizerOptions,
null,
null)
Class<T> c
) {
return recognizeInternal(dialogContext, activity, recognizerOptions, null, null)
.thenApply(recognizerResult -> convertRecognizerResult(recognizerResult, c));
}
/**
* Return results of the analysis (Suggested actions and intents).
* @param turnContext Context object containing information for a single turn of conversation with a user.
* @param recognizerOptions LuisRecognizerOptions instance to be used by the call. This parameter overrides the
* default LuisRecognizerOptions passed in the constructor.
* @param telemetryProperties Additional properties to be logged to telemetry with the LuisResult event.
* @param telemetryMetrics Additional metrics to be logged to telemetry with the LuisResult event.
* @return The LUIS results of the analysis of the current message text in the current turn's context activity.
*
* @param turnContext Context object containing information for a single
* turn of conversation with a user.
* @param recognizerOptions LuisRecognizerOptions instance to be used by the
* call. This parameter overrides the default
* LuisRecognizerOptions passed in the constructor.
* @param telemetryProperties Additional properties to be logged to telemetry
* with the LuisResult event.
* @param telemetryMetrics Additional metrics to be logged to telemetry with
* the LuisResult event.
* @return The LUIS results of the analysis of the current message text in the
* current turn's context activity.
*/
public CompletableFuture<RecognizerResult> recognize(
TurnContext turnContext,
LuisRecognizerOptions recognizerOptions,
Map<String, String> telemetryProperties,
Map<String, Double> telemetryMetrics) {
return recognizeInternal(
turnContext,
recognizerOptions,
telemetryProperties,
telemetryMetrics);
Map<String, Double> telemetryMetrics
) {
return recognizeInternal(turnContext, recognizerOptions, telemetryProperties, telemetryMetrics);
}
/**
* Return results of the analysis (Suggested actions and intents).
* @param dialogContext Context object containing information for a single turn of conversation with a user.
*
* @param dialogContext Context object containing information for a single
* turn of conversation with a user.
* @param activity Activity to recognize.
* @param recognizerOptions A LuisRecognizerOptions instance to be used by the call. This parameter overrides the
* default LuisRecognizerOptions passed in the constructor.
* @param telemetryProperties Additional properties to be logged to telemetry with the LuisResult event.
* @param telemetryMetrics Additional metrics to be logged to telemetry with the LuisResult event.
* @return The LUIS results of the analysis of the current message text in the current turn's context activity.
* @param recognizerOptions A LuisRecognizerOptions instance to be used by the
* call. This parameter overrides the default
* LuisRecognizerOptions passed in the constructor.
* @param telemetryProperties Additional properties to be logged to telemetry
* with the LuisResult event.
* @param telemetryMetrics Additional metrics to be logged to telemetry with
* the LuisResult event.
* @return The LUIS results of the analysis of the current message text in the
* current turn's context activity.
*/
public CompletableFuture<RecognizerResult> recognize(
DialogContext dialogContext,
Activity activity,
LuisRecognizerOptions recognizerOptions,
Map<String, String> telemetryProperties,
Map<String, Double> telemetryMetrics) {
return recognizeInternal(
dialogContext,
activity,
recognizerOptions,
telemetryProperties,
telemetryMetrics);
Map<String, Double> telemetryMetrics
) {
return recognizeInternal(dialogContext, activity, recognizerOptions, telemetryProperties, telemetryMetrics);
}
/**
* Runs an utterance through a recognizer and returns a strongly-typed recognizer result.
* @param turnContext Context object containing information for a single turn of conversation with a user.
* @param recognizerOptions A LuisRecognizerOptions instance to be used by the call. This parameter overrides the
* default LuisRecognizerOptions passed in the constructor.
* @param telemetryProperties Additional properties to be logged to telemetry with the LuisResult event.
* @param telemetryMetrics Additional metrics to be logged to telemetry with the LuisResult event.
* Runs an utterance through a recognizer and returns a strongly-typed
* recognizer result.
*
* @param turnContext Context object containing information for a single
* turn of conversation with a user.
* @param recognizerOptions A LuisRecognizerOptions instance to be used by the
* call. This parameter overrides the default
* LuisRecognizerOptions passed in the constructor.
* @param telemetryProperties Additional properties to be logged to telemetry
* with the LuisResult event.
* @param telemetryMetrics Additional metrics to be logged to telemetry with
* the LuisResult event.
* @param <T> Type of result.
* @param c RecognizerConvert implemented class to convert the Recognizer Result into.
* @return The LUIS results of the analysis of the current message text in the current turn's context activity.
* @param c RecognizerConvert implemented class to convert the
* Recognizer Result into.
* @return The LUIS results of the analysis of the current message text in the
* current turn's context activity.
*/
public <T extends RecognizerConvert> CompletableFuture<T> recognize(
TurnContext turnContext,
LuisRecognizerOptions recognizerOptions,
Map<String, String> telemetryProperties,
Map<String, Double> telemetryMetrics,
Class<T> c) {
return recognizeInternal(
turnContext,
recognizerOptions,
telemetryProperties,
telemetryMetrics)
Class<T> c
) {
return recognizeInternal(turnContext, recognizerOptions, telemetryProperties, telemetryMetrics)
.thenApply(recognizerResult -> convertRecognizerResult(recognizerResult, c));
}
/**
* Runs an utterance through a recognizer and returns a strongly-typed recognizer result.
* @param dialogContext Context object containing information for a single turn of conversation with a user.
* Runs an utterance through a recognizer and returns a strongly-typed
* recognizer result.
*
* @param dialogContext Context object containing information for a single
* turn of conversation with a user.
* @param activity Activity to recognize.
* @param recognizerOptions LuisRecognizerOptions instance to be used by the call. This parameter overrides the
* default LuisRecognizerOptions passed in the constructor.
* @param telemetryProperties Additional properties to be logged to telemetry with the LuisResult event.
* @param telemetryMetrics Additional metrics to be logged to telemetry with the LuisResult event.
* @param recognizerOptions LuisRecognizerOptions instance to be used by the
* call. This parameter overrides the default
* LuisRecognizerOptions passed in the constructor.
* @param telemetryProperties Additional properties to be logged to telemetry
* with the LuisResult event.
* @param telemetryMetrics Additional metrics to be logged to telemetry with
* the LuisResult event.
* @param <T> Type of result.
* @param c RecognizerConvert implemented class to convert the Recognizer Result into.
* @return The LUIS results of the analysis of the current message text in the current turn's context activity.
* @param c RecognizerConvert implemented class to convert the
* Recognizer Result into.
* @return The LUIS results of the analysis of the current message text in the
* current turn's context activity.
*/
public <T extends RecognizerConvert> CompletableFuture<T> recognize(
DialogContext dialogContext,
@ -444,50 +477,46 @@ public class LuisRecognizer extends TelemetryRecognizer {
LuisRecognizerOptions recognizerOptions,
Map<String, String> telemetryProperties,
Map<String, Double> telemetryMetrics,
Class<T> c) {
return recognizeInternal(
dialogContext,
activity,
recognizerOptions,
telemetryProperties,
telemetryMetrics)
Class<T> c
) {
return recognizeInternal(dialogContext, activity, recognizerOptions, telemetryProperties, telemetryMetrics)
.thenApply(recognizerResult -> convertRecognizerResult(recognizerResult, c));
}
/**
* Invoked prior to a LuisResult being logged.
*
* @param recognizerResult The Luis Results for the call.
* @param turnContext Context object containing information for a single turn of conversation with a user.
* @param telemetryProperties Additional properties to be logged to telemetry with the LuisResult event.
* @param telemetryMetrics Additional metrics to be logged to telemetry with the LuisResult event.
* @param turnContext Context object containing information for a single
* turn of conversation with a user.
* @param telemetryProperties Additional properties to be logged to telemetry
* with the LuisResult event.
* @param telemetryMetrics Additional metrics to be logged to telemetry with
* the LuisResult event.
*/
public void onRecognizerResult(
RecognizerResult recognizerResult,
TurnContext turnContext,
Map<String, String> telemetryProperties,
Map<String, Double> telemetryMetrics) {
Map<String, String> properties = fillLuisEventPropertiesAsync(
recognizerResult,
turnContext,
telemetryProperties);
Map<String, Double> telemetryMetrics
) {
Map<String, String> properties =
fillLuisEventPropertiesAsync(recognizerResult, turnContext, telemetryProperties);
// Track the event
this.getTelemetryClient().trackEvent(
LuisTelemetryConstants.LUIS_RESULT,
properties,
telemetryMetrics);
this.getTelemetryClient().trackEvent(LuisTelemetryConstants.LUIS_RESULT, properties, telemetryMetrics);
}
private Map<String, String> fillLuisEventPropertiesAsync(
RecognizerResult recognizerResult,
TurnContext turnContext,
Map<String, String> telemetryProperties) {
Map<String, String> telemetryProperties
) {
Map<String, IntentScore> sortedIntents = sortIntents(recognizerResult);
ArrayList<String> topTwoIntents = new ArrayList<>();
Iterator<Map.Entry<String, IntentScore>> iterator = sortedIntents.entrySet().iterator();
int intentCounter = 0;
while (iterator.hasNext()
&& intentCounter < 2) {
while (iterator.hasNext() && intentCounter < 2) {
intentCounter++;
Map.Entry<String, IntentScore> intent = iterator.next();
topTwoIntents.add(intent.getKey());
@ -497,52 +526,40 @@ public class LuisRecognizer extends TelemetryRecognizer {
Map<String, String> properties = new HashMap<>();
properties.put(
LuisTelemetryConstants.APPLICATION_ID_PROPERTY,
luisRecognizerOptions.getApplication().getApplicationId());
properties.put(
LuisTelemetryConstants.INTENT_PROPERTY,
topTwoIntents.size() > 0 ? topTwoIntents.get(0) : "");
luisRecognizerOptions.getApplication().getApplicationId()
);
properties.put(LuisTelemetryConstants.INTENT_PROPERTY, topTwoIntents.size() > 0 ? topTwoIntents.get(0) : "");
properties.put(
LuisTelemetryConstants.INTENT_SCORE_PROPERTY,
topTwoIntents.size() > 0
? "" + recognizerResult.getIntents().get(topTwoIntents.get(0)).getScore()
: "0.00");
properties.put(
LuisTelemetryConstants.INTENT_2_PROPERTY,
topTwoIntents.size() > 1 ? topTwoIntents.get(1) : "");
topTwoIntents.size() > 0 ? "" + recognizerResult.getIntents().get(topTwoIntents.get(0)).getScore() : "0.00"
);
properties.put(LuisTelemetryConstants.INTENT_2_PROPERTY, topTwoIntents.size() > 1 ? topTwoIntents.get(1) : "");
properties.put(
LuisTelemetryConstants.INTENT_SCORE_2_PROPERTY,
topTwoIntents.size() > 1
? "" + recognizerResult.getIntents().get(topTwoIntents.get(1)).getScore()
: "0.00");
properties.put(
LuisTelemetryConstants.FROM_ID_PROPERTY, turnContext.getActivity().getFrom().getId());
topTwoIntents.size() > 1 ? "" + recognizerResult.getIntents().get(topTwoIntents.get(1)).getScore() : "0.00"
);
properties.put(LuisTelemetryConstants.FROM_ID_PROPERTY, turnContext.getActivity().getFrom().getId());
if (recognizerResult.getProperties().containsKey("sentiment")) {
JsonNode sentiment = recognizerResult.getProperties().get("sentiment");
if (sentiment.has("label")) {
properties.put(
LuisTelemetryConstants.SENTIMENT_LABEL_PROPERTY,
sentiment.get("label").textValue());
properties.put(LuisTelemetryConstants.SENTIMENT_LABEL_PROPERTY, sentiment.get("label").textValue());
}
if (sentiment.has("score")) {
properties.put(
LuisTelemetryConstants.SENTIMENT_SCORE_PROPERTY,
sentiment.get("score").textValue());
properties.put(LuisTelemetryConstants.SENTIMENT_SCORE_PROPERTY, sentiment.get("score").textValue());
}
}
properties.put(
LuisTelemetryConstants.ENTITIES_PROPERTY,
recognizerResult.getEntities().toString());
properties.put(LuisTelemetryConstants.ENTITIES_PROPERTY, recognizerResult.getEntities().toString());
// Use the LogPersonalInformation flag to toggle logging PII data, text is a common example
if (isLogPersonalInformation()
&& turnContext.getActivity().getText() != null
&& !turnContext.getActivity().getText().equals("")) {
properties.put(
LuisTelemetryConstants.QUESTION_PROPERTY,
turnContext.getActivity().getText());
// Use the LogPersonalInformation flag to toggle logging PII data, text is a
// common example
if (
isLogPersonalInformation() && turnContext.getActivity().getText() != null
&& !turnContext.getActivity().getText().equals("")
) {
properties.put(LuisTelemetryConstants.QUESTION_PROPERTY, turnContext.getActivity().getText());
}
// Additional Properties can override "stock" properties.
@ -555,71 +572,62 @@ public class LuisRecognizer extends TelemetryRecognizer {
return properties;
}
private <T extends RecognizerConvert> T convertRecognizerResult(
RecognizerResult recognizerResult,
Class<T> clazz) {
private <T extends RecognizerConvert> T convertRecognizerResult(RecognizerResult recognizerResult, Class<T> clazz) {
T result;
try {
result = clazz.newInstance();
result.convert(recognizerResult);
} catch (InstantiationException | IllegalAccessException e) {
throw new RuntimeException(
String.format("Exception thrown when converting "
+ "Recgonizer Result to strongly typed: %s : %s",
String.format(
"Exception thrown when converting " + "Recgonizer Result to strongly typed: %s : %s",
clazz.getName(),
e.getMessage()));
e.getMessage()
)
);
}
return result;
}
/**
* Returns a RecognizerResult object. This method will call the internal recognize implementation of the
* Luis Recognizer Options.
* Returns a RecognizerResult object. This method will call the internal
* recognize implementation of the Luis Recognizer Options.
*/
private CompletableFuture<RecognizerResult> recognizeInternal(
TurnContext turnContext,
LuisRecognizerOptions options,
Map<String, String> telemetryProperties,
Map<String, Double> telemetryMetrics) {
Map<String, Double> telemetryMetrics
) {
LuisRecognizerOptions predictionOptionsToRun = options == null ? luisRecognizerOptions : options;
return predictionOptionsToRun.recognizeInternal(turnContext)
.thenApply(recognizerResult -> {
onRecognizerResult(
recognizerResult,
turnContext,
telemetryProperties,
telemetryMetrics);
return recognizerResult;
});
return predictionOptionsToRun.recognizeInternal(turnContext).thenApply(recognizerResult -> {
onRecognizerResult(recognizerResult, turnContext, telemetryProperties, telemetryMetrics);
return recognizerResult;
});
}
/**
* Returns a RecognizerResult object. This method will call the internal recognize implementation of the
* Luis Recognizer Options.
* Returns a RecognizerResult object. This method will call the internal
* recognize implementation of the Luis Recognizer Options.
*/
private CompletableFuture<RecognizerResult> recognizeInternal(
DialogContext dialogContext,
Activity activity,
LuisRecognizerOptions options,
Map<String, String> telemetryProperties,
Map<String, Double> telemetryMetrics) {
Map<String, Double> telemetryMetrics
) {
LuisRecognizerOptions predictionOptionsToRun = options == null ? luisRecognizerOptions : options;
return predictionOptionsToRun.recognizeInternal(
dialogContext,
activity)
.thenApply(recognizerResult -> {
onRecognizerResult(
recognizerResult,
dialogContext.getContext(),
telemetryProperties,
telemetryMetrics);
return recognizerResult;
});
return predictionOptionsToRun.recognizeInternal(dialogContext, activity).thenApply(recognizerResult -> {
onRecognizerResult(recognizerResult, dialogContext.getContext(), telemetryProperties, telemetryMetrics);
return recognizerResult;
});
}
private Map<String, IntentScore> sortIntents(RecognizerResult recognizerResult) {
Map<String, IntentScore> sortedIntents = new LinkedHashMap<>();
recognizerResult.getIntents().entrySet()
recognizerResult.getIntents()
.entrySet()
.stream()
.sorted(Map.Entry.comparingByValue(Comparator.comparingDouble(IntentScore::getScore).reversed()))
.forEachOrdered(x -> sortedIntents.put(x.getKey(), x.getValue()));

Просмотреть файл

@ -12,13 +12,15 @@ import com.microsoft.bot.schema.Activity;
import java.util.concurrent.CompletableFuture;
/**
* Abstract class to enforce the Strategy pattern consumed by the Luis Recognizer through the options selected.
* Abstract class to enforce the Strategy pattern consumed by the Luis
* Recognizer through the options selected.
*
*/
public abstract class LuisRecognizerOptions {
/**
* Initializes an instance of the LuisRecognizerOptions implementation.
*
* @param application An instance of LuisApplication".
*/
protected LuisRecognizerOptions(LuisApplication application) {
@ -44,7 +46,8 @@ public abstract class LuisRecognizerOptions {
private boolean logPersonalInformation = false;
/**
* Controls if full results from the LUIS API should be returned with the recognizer result.
* Controls if full results from the LUIS API should be returned with the
* recognizer result.
*/
private boolean includeAPIResults = false;
@ -58,7 +61,8 @@ public abstract class LuisRecognizerOptions {
}
/**
* Gets the currently configured Bot Telemetry Client that logs the LuisResult event.
* Gets the currently configured Bot Telemetry Client that logs the LuisResult
* event.
*
* @return The Bot Telemetry Client.
*/
@ -71,13 +75,13 @@ public abstract class LuisRecognizerOptions {
*
* @param telemetryClient A Bot Telemetry Client instance
*/
public void setTelemetryClient(
BotTelemetryClient telemetryClient) {
public void setTelemetryClient(BotTelemetryClient telemetryClient) {
this.telemetryClient = telemetryClient;
}
/**
* Indicates if personal information should be sent as telemetry.
*
* @return value boolean value to control personal information logging.
*/
public boolean isLogPersonalInformation() {
@ -86,49 +90,53 @@ public abstract class LuisRecognizerOptions {
/**
* Indicates if personal information should be sent as telemetry.
*
* @param logPersonalInformation to set personal information logging preference.
*/
public void setLogPersonalInformation(
boolean logPersonalInformation) {
public void setLogPersonalInformation(boolean logPersonalInformation) {
this.logPersonalInformation = logPersonalInformation;
}
/**
* Indicates if full results from the LUIS API should be returned with the recognizer result.
* @return boolean value showing preference on LUIS API full response added to recognizer result.
* Indicates if full results from the LUIS API should be returned with the
* recognizer result.
*
* @return boolean value showing preference on LUIS API full response added to
* recognizer result.
*/
public boolean isIncludeAPIResults() {
return includeAPIResults;
}
/**
* Indicates if full results from the LUIS API should be returned with the recognizer result.
* @param includeAPIResults to set full Luis API response to be added to the recognizer result.
* Indicates if full results from the LUIS API should be returned with the
* recognizer result.
*
* @param includeAPIResults to set full Luis API response to be added to the
* recognizer result.
*/
public void setIncludeAPIResults(
boolean includeAPIResults) {
public void setIncludeAPIResults(boolean includeAPIResults) {
this.includeAPIResults = includeAPIResults;
}
/**
* Implementation of the Luis API http call and result processing.
* This is intended to follow a Strategy pattern and
* should only be consumed through the LuisRecognizer class.
* Implementation of the Luis API http call and result processing. This is
* intended to follow a Strategy pattern and should only be consumed through the
* LuisRecognizer class.
*
* @param turnContext used to extract the text utterance to be sent to Luis.
* @return Recognizer Result populated by the Luis response.
*/
abstract CompletableFuture<RecognizerResult> recognizeInternal(
TurnContext turnContext);
abstract CompletableFuture<RecognizerResult> recognizeInternal(TurnContext turnContext);
/**
* Implementation of the Luis API http call and result processing.
* This is intended to follow a Strategy pattern and
* should only be consumed through the LuisRecognizer class.
* @param context Dialog Context to extract turn context.
* Implementation of the Luis API http call and result processing. This is
* intended to follow a Strategy pattern and should only be consumed through the
* LuisRecognizer class.
*
* @param context Dialog Context to extract turn context.
* @param activity to extract the text utterance to be sent to Luis.
* @return Recognizer Result populated by the Luis response.
*/
abstract CompletableFuture<RecognizerResult> recognizeInternal(
DialogContext context,
Activity activity);
abstract CompletableFuture<RecognizerResult> recognizeInternal(DialogContext context, Activity activity);
}

Просмотреть файл

@ -40,25 +40,11 @@ import java.util.concurrent.CompletableFuture;
*/
public class LuisRecognizerOptionsV3 extends LuisRecognizerOptions {
private final HashSet<String> dateSubtypes = new HashSet<>(
Arrays.asList(
"date",
"daterange",
"datetime",
"datetimerange",
"duration",
"set",
"time",
"timerange"
));
Arrays.asList("date", "daterange", "datetime", "datetimerange", "duration", "set", "time", "timerange")
);
private final HashSet<String> geographySubtypes = new HashSet<>(
Arrays.asList(
"poi",
"city",
"countryRegion",
"continent",
"state"
));
private final HashSet<String> geographySubtypes =
new HashSet<>(Arrays.asList("poi", "city", "countryRegion", "continent", "state"));
private final String metadataKey = "$instance";
@ -83,36 +69,41 @@ public class LuisRecognizerOptionsV3 extends LuisRecognizerOptions {
private Recognizer externalEntityRecognizer = null;
/**
* Value indicating whether all intents come back or only the top one. True for returning all intents.
* Value indicating whether all intents come back or only the top one. True for
* returning all intents.
*/
private boolean includeAllIntents = false;
/**
* Value indicating whether or not instance data should be included in response.
*/
private boolean includeInstanceData = false;
private boolean includeInstanceData = false;
/**
* Value indicating whether queries should be logged in LUIS. If queries should be logged in LUIS in order to help
* build better models through active learning
* Value indicating whether queries should be logged in LUIS. If queries should
* be logged in LUIS in order to help build better models through active
* learning
*/
private boolean log = true;
private boolean log = true;
/**
* Value indicating whether external entities should override other means of recognizing entities. True if external
* entities should be preferred to the results from LUIS models
* Value indicating whether external entities should override other means of
* recognizing entities. True if external entities should be preferred to the
* results from LUIS models
*/
private boolean preferExternalEntities = true;
/**
* The LUIS slot to use for the application. By default this uses the production slot. You can find other standard
* slots in LuisSlot. If you specify a Version, then a private version of the application is used instead of a slot.
* The LUIS slot to use for the application. By default this uses the production
* slot. You can find other standard slots in LuisSlot. If you specify a
* Version, then a private version of the application is used instead of a slot.
*/
private String slot = LuisSlot.PRODUCTION;
/**
* The specific version of the application to access. LUIS supports versions and this is the version to use instead
* of a slot. If this is specified, then the Slot is ignored.
* The specific version of the application to access. LUIS supports versions and
* this is the version to use instead of a slot. If this is specified, then the
* Slot is ignored.
*/
private String version = null;
@ -132,7 +123,9 @@ public class LuisRecognizerOptionsV3 extends LuisRecognizerOptions {
public static final String LUIS_TRACE_LABEL = "LuisV3 Trace";
/**
* Gets External entity recognizer to recognize external entities to pass to LUIS.
* Gets External entity recognizer to recognize external entities to pass to
* LUIS.
*
* @return externalEntityRecognizer
*/
public Recognizer getExternalEntityRecognizer() {
@ -140,7 +133,9 @@ public class LuisRecognizerOptionsV3 extends LuisRecognizerOptions {
}
/**
* Sets External entity recognizer to recognize external entities to pass to LUIS.
* Sets External entity recognizer to recognize external entities to pass to
* LUIS.
*
* @param externalEntityRecognizer External Recognizer instance.
*/
public void setExternalEntityRecognizer(Recognizer externalEntityRecognizer) {
@ -148,7 +143,9 @@ public class LuisRecognizerOptionsV3 extends LuisRecognizerOptions {
}
/**
* Gets indicating whether all intents come back or only the top one. True for returning all intents.
* Gets indicating whether all intents come back or only the top one. True for
* returning all intents.
*
* @return True for returning all intents.
*/
public boolean isIncludeAllIntents() {
@ -157,6 +154,7 @@ public class LuisRecognizerOptionsV3 extends LuisRecognizerOptions {
/**
* Sets indicating whether all intents come back or only the top one.
*
* @param includeAllIntents True for returning all intents.
*/
public void setIncludeAllIntents(boolean includeAllIntents) {
@ -164,7 +162,9 @@ public class LuisRecognizerOptionsV3 extends LuisRecognizerOptions {
}
/**
* Gets value indicating whether or not instance data should be included in response.
* Gets value indicating whether or not instance data should be included in
* response.
*
* @return True if instance data should be included in response.
*/
public boolean isIncludeInstanceData() {
@ -172,16 +172,21 @@ public class LuisRecognizerOptionsV3 extends LuisRecognizerOptions {
}
/**
* Sets value indicating whether or not instance data should be included in response.
* @param includeInstanceData True if instance data should be included in response.
* Sets value indicating whether or not instance data should be included in
* response.
*
* @param includeInstanceData True if instance data should be included in
* response.
*/
public void setIncludeInstanceData(boolean includeInstanceData) {
this.includeInstanceData = includeInstanceData;
}
/**
* Value indicating whether queries should be logged in LUIS. If queries should be logged in LUIS in order to help
* build better models through active learning
* Value indicating whether queries should be logged in LUIS. If queries should
* be logged in LUIS in order to help build better models through active
* learning
*
* @return True if queries should be logged in LUIS.
*/
public boolean isLog() {
@ -189,8 +194,10 @@ public class LuisRecognizerOptionsV3 extends LuisRecognizerOptions {
}
/**
* Value indicating whether queries should be logged in LUIS. If queries should be logged in LUIS in order to help
* build better models through active learning.
* Value indicating whether queries should be logged in LUIS. If queries should
* be logged in LUIS in order to help build better models through active
* learning.
*
* @param log True if queries should be logged in LUIS.
*/
public void setLog(boolean log) {
@ -199,6 +206,7 @@ public class LuisRecognizerOptionsV3 extends LuisRecognizerOptions {
/**
* Returns Dynamic lists used to recognize entities for a particular query.
*
* @return Dynamic lists used to recognize entities for a particular query
*/
public List<DynamicList> getDynamicLists() {
@ -207,6 +215,7 @@ public class LuisRecognizerOptionsV3 extends LuisRecognizerOptions {
/**
* Sets Dynamic lists used to recognize entities for a particular query.
*
* @param dynamicLists to recognize entities for a particular query.
*/
public void setDynamicLists(List<DynamicList> dynamicLists) {
@ -215,6 +224,7 @@ public class LuisRecognizerOptionsV3 extends LuisRecognizerOptions {
/**
* Gets External entities to be recognized in query.
*
* @return External entities to be recognized in query.
*/
public List<ExternalEntity> getExternalEntities() {
@ -223,6 +233,7 @@ public class LuisRecognizerOptionsV3 extends LuisRecognizerOptions {
/**
* Sets External entities to be recognized in query.
*
* @param externalEntities External entities to be recognized in query.
*/
public void setExternalEntities(List<ExternalEntity> externalEntities) {
@ -230,16 +241,22 @@ public class LuisRecognizerOptionsV3 extends LuisRecognizerOptions {
}
/**
* Gets value indicating whether external entities should override other means of recognizing entities.
* @return True if external entities should be preferred to the results from LUIS models.
* Gets value indicating whether external entities should override other means
* of recognizing entities.
*
* @return True if external entities should be preferred to the results from
* LUIS models.
*/
public boolean isPreferExternalEntities() {
return preferExternalEntities;
}
/**
* Sets value indicating whether external entities should override other means of recognizing entities.
* @param preferExternalEntities True if external entities should be preferred to the results from LUIS models.
* Sets value indicating whether external entities should override other means
* of recognizing entities.
*
* @param preferExternalEntities True if external entities should be preferred
* to the results from LUIS models.
*/
public void setPreferExternalEntities(boolean preferExternalEntities) {
this.preferExternalEntities = preferExternalEntities;
@ -247,6 +264,7 @@ public class LuisRecognizerOptionsV3 extends LuisRecognizerOptions {
/**
* Gets datetimeV2 offset. The format for the datetimeReference is ISO 8601.
*
* @return The format for the datetimeReference in ISO 8601.
*/
public String getDateTimeReference() {
@ -255,6 +273,7 @@ public class LuisRecognizerOptionsV3 extends LuisRecognizerOptions {
/**
* Sets datetimeV2 offset.
*
* @param dateTimeReference The format for the datetimeReference is ISO 8601.
*/
public void setDateTimeReference(String dateTimeReference) {
@ -262,9 +281,11 @@ public class LuisRecognizerOptionsV3 extends LuisRecognizerOptions {
}
/**
* Gets the LUIS slot to use for the application. By default this uses the production slot.
* You can find other standard slots in LuisSlot. If you specify a Version,
* then a private version of the application is used instead of a slot.
* Gets the LUIS slot to use for the application. By default this uses the
* production slot. You can find other standard slots in LuisSlot. If you
* specify a Version, then a private version of the application is used instead
* of a slot.
*
* @return LuisSlot constant.
*/
public String getSlot() {
@ -272,9 +293,11 @@ public class LuisRecognizerOptionsV3 extends LuisRecognizerOptions {
}
/**
* Sets the LUIS slot to use for the application. By default this uses the production slot.
* You can find other standard slots in LuisSlot. If you specify a Version,
* then a private version of the application is used instead of a slot.
* Sets the LUIS slot to use for the application. By default this uses the
* production slot. You can find other standard slots in LuisSlot. If you
* specify a Version, then a private version of the application is used instead
* of a slot.
*
* @param slot LuisSlot value to use.
*/
public void setSlot(String slot) {
@ -282,9 +305,10 @@ public class LuisRecognizerOptionsV3 extends LuisRecognizerOptions {
}
/**
* Gets the specific version of the application to access.
* LUIS supports versions and this is the version to use instead of a slot.
* If this is specified, then the Slot is ignored.
* Gets the specific version of the application to access. LUIS supports
* versions and this is the version to use instead of a slot. If this is
* specified, then the Slot is ignored.
*
* @return Luis application version to Query.
*/
public String getVersion() {
@ -292,9 +316,11 @@ public class LuisRecognizerOptionsV3 extends LuisRecognizerOptions {
}
/**
* Sets the specific version of the application to access.
* LUIS supports versions and this is the version to use instead of a slot.
* @param version Luis Application version. If this is specified, then the Slot is ignored.
* Sets the specific version of the application to access. LUIS supports
* versions and this is the version to use instead of a slot.
*
* @param version Luis Application version. If this is specified, then the Slot
* is ignored.
*/
public void setVersion(String version) {
this.version = version;
@ -302,6 +328,7 @@ public class LuisRecognizerOptionsV3 extends LuisRecognizerOptions {
/**
* Gets whether the http client.
*
* @return OkHttpClient used to query the Luis Service.
*/
public OkHttpClient getHttpClient() {
@ -310,6 +337,7 @@ public class LuisRecognizerOptionsV3 extends LuisRecognizerOptions {
/**
* Sets the http client.
*
* @param httpClient to use for Luis Service http calls.
*/
public void setHttpClient(OkHttpClient httpClient) {
@ -318,6 +346,7 @@ public class LuisRecognizerOptionsV3 extends LuisRecognizerOptions {
/**
* Initializes a new instance of the LuisRecognizerOptionsV3.
*
* @param application Luis Application instance to query.
*/
public LuisRecognizerOptionsV3(LuisApplication application) {
@ -325,111 +354,83 @@ public class LuisRecognizerOptionsV3 extends LuisRecognizerOptions {
}
/**
* Internal implementation of the http request to the LUIS service and parsing of the response to a
* Recognizer Result instance.
* Internal implementation of the http request to the LUIS service and parsing
* of the response to a Recognizer Result instance.
*
* @param dialogContext Context Object.
* @param activity Activity object to extract the utterance.
* @param activity Activity object to extract the utterance.
*/
@Override
CompletableFuture<RecognizerResult> recognizeInternal(
DialogContext dialogContext,
Activity activity
) {
CompletableFuture<RecognizerResult> recognizeInternal(DialogContext dialogContext, Activity activity) {
if (externalEntityRecognizer == null) {
return recognizeInternal(
dialogContext.getContext(),
activity.getText());
return recognizeInternal(dialogContext.getContext(), activity.getText());
}
// call external entity recognizer
List<ExternalEntity> originalExternalEntities = externalEntities;
return externalEntityRecognizer
.recognize(dialogContext, activity)
.thenCompose(
matches -> {
if (matches.getEntities() == null
|| matches.getEntities().toString().equals("{}")) {
return recognizeInternal(
dialogContext.getContext(),
activity.getText());
return externalEntityRecognizer.recognize(dialogContext, activity).thenCompose(matches -> {
if (matches.getEntities() == null || matches.getEntities().toString().equals("{}")) {
return recognizeInternal(dialogContext.getContext(), activity.getText());
}
List<ExternalEntity> recognizerExternalEntities = new ArrayList<>();
JsonNode entities = matches.getEntities();
JsonNode instance = entities.get("$instance");
if (instance == null) {
return recognizeInternal(dialogContext.getContext(), activity.getText());
}
Iterator<Map.Entry<String, JsonNode>> instanceEntitiesIterator = instance.fields();
while (instanceEntitiesIterator.hasNext()) {
Map.Entry<String, JsonNode> property = instanceEntitiesIterator.next();
if (property.getKey().equals("text") || property.getKey().equals("$instance")) {
continue;
}
ArrayNode instances = (ArrayNode) instance.get(property.getKey());
ArrayNode values = (ArrayNode) property.getValue();
if (instances == null || values == null || instances.size() != values.size()) {
continue;
}
for (JsonNode childInstance : values) {
if (childInstance != null && childInstance.has("startIndex") && childInstance.has("endIndex")) {
int start = childInstance.get("startIndex").asInt();
int end = childInstance.get("endIndex").asInt();
recognizerExternalEntities
.add(new ExternalEntity(property.getKey(), start, end - start, property.getValue()));
}
}
recognizerExternalEntities
.addAll(originalExternalEntities == null ? new ArrayList<>() : originalExternalEntities);
externalEntities = recognizerExternalEntities;
}
List<ExternalEntity> recognizerExternalEntities = new ArrayList<>();
JsonNode entities = matches.getEntities();
JsonNode instance = entities.get("$instance");
if (instance == null) {
return recognizeInternal(
dialogContext.getContext(),
activity.getText());
}
Iterator<Map.Entry<String, JsonNode>> instanceEntitiesIterator = instance.fields();
while (instanceEntitiesIterator.hasNext()) {
Map.Entry<String, JsonNode> property = instanceEntitiesIterator.next();
if (property.getKey().equals("text")
|| property.getKey().equals("$instance")) {
continue;
}
ArrayNode instances = (ArrayNode) instance.get(property.getKey());
ArrayNode values = (ArrayNode) property.getValue();
if (instances == null
|| values == null
|| instances.size() != values.size()) {
continue;
}
for (JsonNode childInstance : values) {
if (childInstance != null
&& childInstance.has("startIndex")
&& childInstance.has("endIndex")) {
int start = childInstance.get("startIndex").asInt();
int end = childInstance.get("endIndex").asInt();
recognizerExternalEntities.add(new ExternalEntity(
property.getKey(),
start,
end - start,
property.getValue()));
}
}
recognizerExternalEntities.addAll(
originalExternalEntities == null
? new ArrayList<>()
: originalExternalEntities
);
externalEntities = recognizerExternalEntities;
}
return recognizeInternal(dialogContext.getContext(), activity.getText())
.thenApply(recognizerResult -> {
externalEntities = originalExternalEntities;
return recognizerResult;
});
return recognizeInternal(dialogContext.getContext(), activity.getText()).thenApply(recognizerResult -> {
externalEntities = originalExternalEntities;
return recognizerResult;
});
});
}
/**
* Internal implementation of the http request to the LUIS service and parsing of the response to a
* Recognizer Result instance.
* Internal implementation of the http request to the LUIS service and parsing
* of the response to a Recognizer Result instance.
*
* @param turnContext Context Object.
*/
@Override
CompletableFuture<RecognizerResult> recognizeInternal(
TurnContext turnContext) {
return recognizeInternal(
turnContext,
turnContext.getActivity().getText());
CompletableFuture<RecognizerResult> recognizeInternal(TurnContext turnContext) {
return recognizeInternal(turnContext, turnContext.getActivity().getText());
}
private Request buildRequest(RequestBody body) {
StringBuilder path = new StringBuilder(getApplication().getEndpoint());
path.append(String.format(
"/luis/prediction/v3.0/apps/%s",
getApplication().getApplicationId()));
path.append(String.format("/luis/prediction/v3.0/apps/%s", getApplication().getApplicationId()));
if (version == null) {
path.append(String.format("/slots/%s/predict", slot));
@ -443,9 +444,9 @@ public class LuisRecognizerOptionsV3 extends LuisRecognizerOptions {
httpBuilder.addQueryParameter("log", Boolean.toString(log));
httpBuilder.addQueryParameter("show-all-intents", Boolean.toString(includeAllIntents));
Request.Builder requestBuilder = new Request.Builder()
.url(httpBuilder.build())
.addHeader("Ocp-Apim-Subscription-Key", getApplication().getEndpointKey()).post(body);
Request.Builder requestBuilder = new Request.Builder().url(httpBuilder.build())
.addHeader("Ocp-Apim-Subscription-Key", getApplication().getEndpointKey())
.post(body);
return requestBuilder.build();
}
@ -453,15 +454,11 @@ public class LuisRecognizerOptionsV3 extends LuisRecognizerOptions {
ObjectMapper mapper = new ObjectMapper();
ObjectNode content = JsonNodeFactory.instance.objectNode().put("query", utterance);
ObjectNode queryOptions = JsonNodeFactory.instance.objectNode().put(
"preferExternalEntities",
preferExternalEntities);
ObjectNode queryOptions =
JsonNodeFactory.instance.objectNode().put("preferExternalEntities", preferExternalEntities);
if (dateTimeReference != null
&& !dateTimeReference.isEmpty()) {
queryOptions.put(
"datetimeReference",
dateTimeReference);
if (dateTimeReference != null && !dateTimeReference.isEmpty()) {
queryOptions.put("datetimeReference", dateTimeReference);
}
content.set("options", queryOptions);
@ -478,21 +475,21 @@ public class LuisRecognizerOptionsV3 extends LuisRecognizerOptions {
}
String contentAsText = mapper.writeValueAsString(content);
return RequestBody.create(contentAsText, MediaType.parse("application/json; charset=utf-8"));
return RequestBody.create(MediaType.parse("application/json; charset=utf-8"), contentAsText);
}
private CompletableFuture<RecognizerResult> recognizeInternal(
TurnContext turnContext,
String utterance) {
private CompletableFuture<RecognizerResult> recognizeInternal(TurnContext turnContext, String utterance) {
RecognizerResult recognizerResult;
JsonNode luisResponse = null;
ObjectMapper mapper = new ObjectMapper();
if (utterance == null || utterance.isEmpty()) {
recognizerResult = new RecognizerResult() {{
setText(utterance);
}};
recognizerResult = new RecognizerResult() {
{
setText(utterance);
}
};
} else {
try {
Request request = buildRequest(buildRequestBody(utterance));
@ -503,9 +500,9 @@ public class LuisRecognizerOptionsV3 extends LuisRecognizerOptions {
}
} catch (IOException e) {
CompletableFuture<RecognizerResult> exceptionResult = new CompletableFuture<>();
exceptionResult.completeExceptionally(e);
return exceptionResult;
CompletableFuture<RecognizerResult> exceptionResult = new CompletableFuture<>();
exceptionResult.completeExceptionally(e);
return exceptionResult;
}
JsonNode prediction = luisResponse.get("prediction");
@ -523,14 +520,12 @@ public class LuisRecognizerOptionsV3 extends LuisRecognizerOptions {
recognizerResult.getProperties().put("luisResult", luisResponse);
}
if (includeInstanceData
&& recognizerResult.getEntities().get(metadataKey) == null) {
if (includeInstanceData && recognizerResult.getEntities().get(metadataKey) == null) {
((ObjectNode) recognizerResult.getEntities()).putObject(metadataKey);
}
}
return sendTraceActivity(recognizerResult, luisResponse, turnContext)
.thenApply(v -> recognizerResult);
return sendTraceActivity(recognizerResult, luisResponse, turnContext).thenApply(v -> recognizerResult);
}
@ -544,26 +539,22 @@ public class LuisRecognizerOptionsV3 extends LuisRecognizerOptions {
for (Iterator<Map.Entry<String, JsonNode>> it = intentsObject.fields(); it.hasNext();) {
Map.Entry<String, JsonNode> intent = it.next();
double score = intent.getValue()
.get("score")
.asDouble();
String intentName = intent.getKey()
.replace(".", "_")
.replace(" ", "_");
intents.put(intentName, new IntentScore() {{
setScore(score);
}});
double score = intent.getValue().get("score").asDouble();
String intentName = intent.getKey().replace(".", "_").replace(" ", "_");
intents.put(intentName, new IntentScore() {
{
setScore(score);
}
});
}
return intents;
}
private String normalizeEntity(String entity) {
// Type::Role -> Role
// Type::Role -> Role
String[] type = entity.split(":");
return type[type.length - 1]
.replace(".", "_")
.replace(" ", "_");
return type[type.length - 1].replace(".", "_").replace(" ", "_");
}
private JsonNode getEntities(JsonNode prediction) {
@ -571,30 +562,25 @@ public class LuisRecognizerOptionsV3 extends LuisRecognizerOptions {
return JsonNodeFactory.instance.objectNode();
}
return mapEntitiesRecursive(prediction.get("entities"), false);
return mapEntitiesRecursive(prediction.get("entities"), false);
}
// Exact Port from C#
private JsonNode mapEntitiesRecursive(
JsonNode source,
boolean inInstance) {
private JsonNode mapEntitiesRecursive(JsonNode source, boolean inInstance) {
JsonNode result = source;
if (!source.isArray()
&& source.isObject()) {
if (!source.isArray() && source.isObject()) {
ObjectNode nobj = JsonNodeFactory.instance.objectNode();
// Fix datetime by reverting to simple timex
JsonNode obj = source;
JsonNode type = source.get("type");
if (!inInstance
&& type != null
&& dateSubtypes.contains(type.asText())) {
if (!inInstance && type != null && dateSubtypes.contains(type.asText())) {
JsonNode timexs = obj.get("values");
ArrayNode arr = JsonNodeFactory.instance.arrayNode();
if (timexs != null) {
Set<String> unique = new HashSet<>();
for (JsonNode elt: timexs) {
for (JsonNode elt : timexs) {
unique.add(elt.get("timex").textValue());
}
@ -615,15 +601,11 @@ public class LuisRecognizerOptionsV3 extends LuisRecognizerOptions {
boolean isArray = property.getValue().isArray();
boolean isString = property.getValue().isTextual();
boolean isInt = property.getValue().isInt();
JsonNode val = mapEntitiesRecursive(
property.getValue(),
inInstance || name.equals(metadataKey));
JsonNode val = mapEntitiesRecursive(property.getValue(), inInstance || name.equals(metadataKey));
if (name.equals("datetime")
&& isArray) {
if (name.equals("datetime") && isArray) {
nobj.set("datetimeV1", val);
} else if (name.equals("datetimeV2")
&& isArray) {
} else if (name.equals("datetimeV2") && isArray) {
nobj.set("datetime", val);
} else if (inInstance) {
// Correct $instance issues
@ -633,8 +615,9 @@ public class LuisRecognizerOptionsV3 extends LuisRecognizerOptions {
value += obj.get("startIndex").intValue();
}
nobj.put("endIndex", value);
} else if (!((isInt && name.equals("modelTypeId")) || //NOPMD
(isString && name.equals("role")))) { //NOPMD
} else if (!((isInt && name.equals("modelTypeId")) || // NOPMD
(isString && name.equals("role"))) // NOPMD
) { // NOPMD
nobj.set(name, val);
}
} else {
@ -664,8 +647,7 @@ public class LuisRecognizerOptionsV3 extends LuisRecognizerOptions {
break;
}
if (props.getKey().contains("type")
&& geographySubtypes.contains(props.getValue().textValue())) {
if (props.getKey().contains("type") && geographySubtypes.contains(props.getValue().textValue())) {
isGeographyV2 = props.getValue().textValue();
break;
}
@ -694,9 +676,7 @@ public class LuisRecognizerOptionsV3 extends LuisRecognizerOptions {
return result;
}
private void addProperties(
JsonNode prediction,
RecognizerResult result) {
private void addProperties(JsonNode prediction, RecognizerResult result) {
JsonNode sentiment = prediction.get("sentiment");
if (sentiment != null) {
ObjectNode sentimentNode = JsonNodeFactory.instance.objectNode();
@ -709,21 +689,18 @@ public class LuisRecognizerOptionsV3 extends LuisRecognizerOptions {
private CompletableFuture<ResourceResponse> sendTraceActivity(
RecognizerResult recognizerResult,
JsonNode luisResponse,
TurnContext turnContext) {
TurnContext turnContext
) {
ObjectMapper mapper = new ObjectMapper();
try {
ObjectNode traceInfo = JsonNodeFactory.instance.objectNode();
traceInfo.put(
"recognizerResult",
mapper.writerWithDefaultPrettyPrinter().writeValueAsString(recognizerResult));
traceInfo.set(
"luisResult",
luisResponse);
traceInfo
.put("recognizerResult", mapper.writerWithDefaultPrettyPrinter().writeValueAsString(recognizerResult));
traceInfo.set("luisResult", luisResponse);
traceInfo.set(
"luisModel",
JsonNodeFactory.instance.objectNode()
.put("ModelId",
getApplication().getApplicationId()));
JsonNodeFactory.instance.objectNode().put("ModelId", getApplication().getApplicationId())
);
ObjectNode luisOptions = JsonNodeFactory.instance.objectNode();
luisOptions.put("includeAllIntents", includeAllIntents);
@ -734,7 +711,6 @@ public class LuisRecognizerOptionsV3 extends LuisRecognizerOptions {
luisOptions.put("slot", slot);
luisOptions.put("version", version);
if (externalEntities != null) {
ArrayNode externalEntitiesNode = JsonNodeFactory.instance.arrayNode();
for (ExternalEntity e : externalEntities) {
@ -754,11 +730,8 @@ public class LuisRecognizerOptionsV3 extends LuisRecognizerOptions {
traceInfo.set("luisOptions", luisOptions);
return turnContext.sendActivity(
Activity.createTraceActivity(
"LuisRecognizer",
LUIS_TRACE_TYPE,
traceInfo,
LUIS_TRACE_LABEL));
Activity.createTraceActivity("LuisRecognizer", LUIS_TRACE_TYPE, traceInfo, LUIS_TRACE_LABEL)
);
} catch (IOException e) {
CompletableFuture<ResourceResponse> exceptionResult = new CompletableFuture<>();

Просмотреть файл

@ -9,14 +9,14 @@ package com.microsoft.bot.ai.luis;
*/
public final class LuisSlot {
//Not Called
// Not Called
private LuisSlot() {
}
/**
* Production slot on LUIS.
*/
* Production slot on LUIS.
*/
public static final String PRODUCTION = "production";
/**

Просмотреть файл

@ -7,7 +7,7 @@ package com.microsoft.bot.ai.luis;
* Utility class to set the telemetry values for the Luis Recognizer.
*
*/
public final class LuisTelemetryConstants {
public final class LuisTelemetryConstants {
private LuisTelemetryConstants() {
@ -16,7 +16,7 @@ public final class LuisTelemetryConstants {
/**
* The Key used when storing a LUIS Result in a custom event within telemetry.
*/
public static final String LUIS_RESULT = "LuisResult"; // Event name
public static final String LUIS_RESULT = "LuisResult"; // Event name
/**
* The Key used when storing a LUIS app ID in a custom event within telemetry.
@ -29,7 +29,8 @@ public final class LuisTelemetryConstants {
public static final String INTENT_PROPERTY = "intent";
/**
* The Key used when storing a LUIS intent score in a custom event within telemetry.
* The Key used when storing a LUIS intent score in a custom event within
* telemetry.
*/
public static final String INTENT_SCORE_PROPERTY = "intentScore";
@ -39,7 +40,8 @@ public final class LuisTelemetryConstants {
public static final String INTENT_2_PROPERTY = "intent2";
/**
* The Key used when storing a LUIS intent score in a custom event within telemetry.
* The Key used when storing a LUIS intent score in a custom event within
* telemetry.
*/
public static final String INTENT_SCORE_2_PROPERTY = "intentScore2";
@ -59,12 +61,14 @@ public final class LuisTelemetryConstants {
public static final String ACTIVITY_ID_PROPERTY = "activityId";
/**
* The Key used when storing a sentiment label in a custom event within telemetry.
* The Key used when storing a sentiment label in a custom event within
* telemetry.
*/
public static final String SENTIMENT_LABEL_PROPERTY = "sentimentLabel";
/**
* The Key used when storing a LUIS sentiment score in a custom event within telemetry.
* The Key used when storing a LUIS sentiment score in a custom event within
* telemetry.
*/
public static final String SENTIMENT_SCORE_PROPERTY = "sentimentScore";

Просмотреть файл

@ -24,6 +24,7 @@ public abstract class TelemetryRecognizer implements Recognizer {
/**
* Indicates if personal information should be sent as telemetry.
*
* @return value boolean value to control personal information logging.
*/
public boolean isLogPersonalInformation() {
@ -32,6 +33,7 @@ public abstract class TelemetryRecognizer implements Recognizer {
/**
* Indicates if personal information should be sent as telemetry.
*
* @param logPersonalInformation to set personal information logging preference.
*/
protected void setLogPersonalInformation(boolean logPersonalInformation) {
@ -39,7 +41,9 @@ public abstract class TelemetryRecognizer implements Recognizer {
}
/**
* Gets the currently configured Bot Telemetry Client that logs the LuisResult event.
* Gets the currently configured Bot Telemetry Client that logs the LuisResult
* event.
*
* @return The Bot Telemetry Client.
*/
protected BotTelemetryClient getTelemetryClient() {
@ -47,7 +51,9 @@ public abstract class TelemetryRecognizer implements Recognizer {
}
/**
* Sets the currently configured Bot Telemetry Client that logs the LuisResult event.
* Sets the currently configured Bot Telemetry Client that logs the LuisResult
* event.
*
* @param telemetryClient Bot Telemetry Client.
*/
public void setTelemetryClient(BotTelemetryClient telemetryClient) {
@ -56,29 +62,41 @@ public abstract class TelemetryRecognizer implements Recognizer {
/**
* Return results of the analysis (Suggested actions and intents).
* @param turnContext Context object containing information for a single turn of conversation with a user.
* @param telemetryProperties Additional properties to be logged to telemetry with the LuisResult event.
* @param telemetryMetrics Additional metrics to be logged to telemetry with the LuisResult event.
* @return The LUIS results of the analysis of the current message text in the current turn's context activity.
*
* @param turnContext Context object containing information for a single
* turn of conversation with a user.
* @param telemetryProperties Additional properties to be logged to telemetry
* with the LuisResult event.
* @param telemetryMetrics Additional metrics to be logged to telemetry with
* the LuisResult event.
* @return The LUIS results of the analysis of the current message text in the
* current turn's context activity.
*/
abstract CompletableFuture<RecognizerResult> recognize(
abstract CompletableFuture<RecognizerResult> recognize(
TurnContext turnContext,
Map<String, String> telemetryProperties,
Map<String, Double> telemetryMetrics);
Map<String, Double> telemetryMetrics
);
/**
* Return results of the analysis (Suggested actions and intents).
* @param turnContext Context object containing information for a single turn of conversation with a user.
* @param telemetryProperties Additional properties to be logged to telemetry with the LuisResult event.
* @param telemetryMetrics Additional metrics to be logged to telemetry with the LuisResult event.
* @param <T> Result type.
* @param c The recognition result type class
* @return The LUIS results of the analysis of the current message text in the current turn's context activity.
*
* @param turnContext Context object containing information for a single
* turn of conversation with a user.
* @param telemetryProperties Additional properties to be logged to telemetry
* with the LuisResult event.
* @param telemetryMetrics Additional metrics to be logged to telemetry with
* the LuisResult event.
* @param <T> Result type.
* @param c The recognition result type class
* @return The LUIS results of the analysis of the current message text in the
* current turn's context activity.
*/
abstract <T extends RecognizerConvert> CompletableFuture<T> recognize(
abstract <T extends RecognizerConvert> CompletableFuture<T> recognize(
TurnContext turnContext,
Map<String, String> telemetryProperties,
Map<String, Double> telemetryMetrics,
Class<T> c);
Class<T> c
);
}

Просмотреть файл

@ -3,9 +3,8 @@
package com.microsoft.bot.ai.luis;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.Assert;
import org.junit.Test;
public class LuisApplicationTests {
String validUUID = "b31aeaf3-3511-495b-a07f-571fc873214b";
@ -16,7 +15,7 @@ public class LuisApplicationTests {
@Test
public void invalidSubscriptionKey() {
Exception exception = assertThrows(IllegalArgumentException.class, () -> {
Exception exception = Assert.assertThrows(IllegalArgumentException.class, () -> {
LuisApplication lA = new LuisApplication(
validUUID,
invalidUUID,
@ -26,13 +25,13 @@ public class LuisApplicationTests {
String expectedMessage = String.format("%s is not a valid LUIS subscription key.", invalidUUID);
String actualMessage = exception.getMessage();
assertTrue(actualMessage.contains(expectedMessage));
Assert.assertTrue(actualMessage.contains(expectedMessage));
}
@Test
public void invalidApplicationId () {
Exception exception = assertThrows(IllegalArgumentException.class, () -> {
Exception exception = Assert.assertThrows(IllegalArgumentException.class, () -> {
LuisApplication lA = new LuisApplication(
invalidUUID,
validUUID,
@ -42,13 +41,13 @@ public class LuisApplicationTests {
String expectedMessage = String.format("%s is not a valid LUIS application id.", invalidUUID);
String actualMessage = exception.getMessage();
assertTrue(actualMessage.contains(expectedMessage));
Assert.assertTrue(actualMessage.contains(expectedMessage));
}
@Test
public void invalidEndpoint() {
Exception exception = assertThrows(IllegalArgumentException.class, () -> {
Exception exception = Assert.assertThrows(IllegalArgumentException.class, () -> {
LuisApplication lA = new LuisApplication(
validUUID,
validUUID,
@ -58,7 +57,7 @@ public class LuisApplicationTests {
String expectedMessage = String.format("%s is not a valid LUIS endpoint.", invalidEndpoint);
String actualMessage = exception.getMessage();
assertTrue(actualMessage.contains(expectedMessage));
Assert.assertTrue(actualMessage.contains(expectedMessage));
}
@Test
@ -70,9 +69,9 @@ public class LuisApplicationTests {
validEndpoint
);
assertTrue(lA.getApplicationId().equals(validUUID));
assertTrue(lA.getEndpointKey().equals(validUUID));
assertTrue(lA.getEndpoint().equals(validEndpoint));
Assert.assertTrue(lA.getApplicationId().equals(validUUID));
Assert.assertTrue(lA.getEndpointKey().equals(validUUID));
Assert.assertTrue(lA.getEndpoint().equals(validEndpoint));
}
@Test
@ -80,10 +79,8 @@ public class LuisApplicationTests {
String url = "https://westus.api.cognitive.microsoft.com/luis/prediction/v3.0/apps/b31aeaf3-3511-495b-a07f-571fc873214b/slots/production/predict?verbose=true&timezoneOffset=-360&subscription-key=048ec46dc58e495482b0c447cfdbd291";
LuisApplication lA = new LuisApplication(url);
assertTrue(lA.getApplicationId().equals("b31aeaf3-3511-495b-a07f-571fc873214b"));
assertTrue(lA.getEndpointKey().equals("048ec46dc58e495482b0c447cfdbd291"));
assertTrue(lA.getEndpoint().equals("https://westus.api.cognitive.microsoft.com"));
Assert.assertTrue(lA.getApplicationId().equals("b31aeaf3-3511-495b-a07f-571fc873214b"));
Assert.assertTrue(lA.getEndpointKey().equals("048ec46dc58e495482b0c447cfdbd291"));
Assert.assertTrue(lA.getEndpoint().equals("https://westus.api.cognitive.microsoft.com"));
}
}

Просмотреть файл

@ -22,12 +22,10 @@ import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.RecordedRequest;
import org.apache.commons.io.FileUtils;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.junit.MockitoJUnitRunner;
import java.io.File;
import java.io.IOException;
@ -43,7 +41,7 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
@ExtendWith(MockitoExtension.class)
@RunWith(MockitoJUnitRunner.class)
public class LuisRecognizerOptionsV3Tests {
@Mock
@ -60,31 +58,39 @@ public class LuisRecognizerOptionsV3Tests {
String subscriptionKey = "b31aeaf3-3511-495b-a07f-571fc873214b";
boolean mockLuisResponse = true;
@ParameterizedTest
@ValueSource(strings = {
"Composite1.json",
"Composite2.json",
"Composite3.json",
"DateTimeReference.json",
"DynamicListsAndList.json",
"ExternalEntitiesAndBuiltin.json",
"ExternalEntitiesAndComposite.json",
"ExternalEntitiesAndList.json",
"ExternalEntitiesAndRegex.json",
"ExternalEntitiesAndSimple.json",
"ExternalEntitiesAndSimpleOverride.json",
"GeoPeopleOrdinal.json",
"Minimal.json",
@Test
public void shouldParseLuisResponsesCorrectly_TurnContextPassed() {
String[] files = {
"Composite1.json",
"Composite2.json",
"Composite3.json",
"DateTimeReference.json",
"DynamicListsAndList.json",
"ExternalEntitiesAndBuiltin.json",
"ExternalEntitiesAndComposite.json",
"ExternalEntitiesAndList.json",
"ExternalEntitiesAndRegex.json",
"ExternalEntitiesAndSimple.json",
"ExternalEntitiesAndSimpleOverride.json",
"GeoPeopleOrdinal.json",
"Minimal.json",
// "MinimalWithGeo.json",
"NoEntitiesInstanceTrue.json",
"Patterns.json",
"Prebuilt.json",
"roles.json",
"TraceActivity.json",
"Typed.json",
"TypedPrebuilt.json"
}) // six numbers
public void shouldParseLuisResponsesCorrectly_TurnContextPassed(String fileName) {
"NoEntitiesInstanceTrue.json",
"Patterns.json",
"Prebuilt.json",
"roles.json",
"TraceActivity.json",
"Typed.json",
"TypedPrebuilt.json"
};
for (String file : files) {
shouldParseLuisResponsesCorrectly_TurnContextPassed(file);
reset(turnContext);
}
}
private void shouldParseLuisResponsesCorrectly_TurnContextPassed(String fileName) {
RecognizerResult result = null, expected = null;
MockWebServer mockWebServer = new MockWebServer();

Просмотреть файл

@ -15,21 +15,20 @@ import com.microsoft.bot.dialogs.DialogContext;
import com.microsoft.bot.schema.Activity;
import com.microsoft.bot.schema.ActivityTypes;
import com.microsoft.bot.schema.ChannelAccount;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import static org.junit.Assert.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.*;
@ExtendWith(MockitoExtension.class)
@RunWith(MockitoJUnitRunner.class)
public class LuisRecognizerTests {
@Mock
@ -90,14 +89,14 @@ public class LuisRecognizerTests {
@Test
public void topIntentThrowsIllegalArgumentIfResultIsNull() {
Exception exception = assertThrows(IllegalArgumentException.class, () -> {
Exception exception = Assert.assertThrows(IllegalArgumentException.class, () -> {
LuisRecognizer.topIntent(null);
});
String expectedMessage = "RecognizerResult";
String actualMessage = exception.getMessage();
assertTrue(actualMessage.contains(expectedMessage));
Assert.assertTrue(actualMessage.contains(expectedMessage));
}
@Test
@ -108,12 +107,12 @@ public class LuisRecognizerTests {
@Test
public void throwExceptionOnNullOptions() {
Exception exception = assertThrows(IllegalArgumentException.class, () -> {
Exception exception = Assert.assertThrows(IllegalArgumentException.class, () -> {
LuisRecognizer lR = new LuisRecognizer(null);
});
String actualMessage = exception.getMessage();
assertTrue(actualMessage.contains("Recognizer Options cannot be null"));
Assert.assertTrue(actualMessage.contains("Recognizer Options cannot be null"));
}
@Test
@ -147,7 +146,7 @@ public class LuisRecognizerTests {
assertEquals(mapper.writeValueAsString(expected), mapper.writeValueAsString(actual));
} catch (InterruptedException | ExecutionException | JsonProcessingException e) {
e.printStackTrace();
assertTrue(false);
Assert.assertTrue(false);
}
}
@ -202,7 +201,7 @@ public class LuisRecognizerTests {
assertEquals(mapper.writeValueAsString(expected), mapper.writeValueAsString(actual));
} catch (InterruptedException | ExecutionException | JsonProcessingException e) {
e.printStackTrace();
assertTrue(false);
Assert.assertTrue(false);
}
}
@ -261,7 +260,7 @@ public class LuisRecognizerTests {
assertEquals(mapper.writeValueAsString(expected), mapper.writeValueAsString(actual));
} catch (InterruptedException | ExecutionException | JsonProcessingException e) {
e.printStackTrace();
assertTrue(false);
Assert.assertTrue(false);
}
}

Просмотреть файл

@ -236,7 +236,7 @@
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.0.0</version>
<version>3.8.0</version>
<scope>test</scope>
</dependency>
@ -513,9 +513,6 @@
<coberturaReport>
./cobertura-report/bot-connector/coverage.xml
</coberturaReport>
<coberturaReport>
./cobertura-report/bot-connector-sample/coverage.xml
</coberturaReport>
</coberturaReports>
<sourceEncoding>UTF-8</sourceEncoding>