Skip to content

Commit

Permalink
Adding dialog directives
Browse files Browse the repository at this point in the history
  • Loading branch information
LeandroPas committed May 12, 2017
1 parent c23055e commit 40ab702
Show file tree
Hide file tree
Showing 14 changed files with 444 additions and 19 deletions.
8 changes: 4 additions & 4 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<groupId>com.amazon.alexa</groupId>
<artifactId>alexa-skills-kit</artifactId>
<packaging>jar</packaging>
<version>1.3.0</version>
<version>1.3.1</version>
<name>Alexa Skills Kit</name>
<description>Contains classes used by the Alexa Skills Kit.</description>
<url>http://developer.amazon.com/ask</url>
Expand Down Expand Up @@ -37,17 +37,17 @@
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.3.2</version>
<version>2.6.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.3.2</version>
<version>2.6.7</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.3.2</version>
<version>2.6.7</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
Expand Down
3 changes: 3 additions & 0 deletions src/com/amazon/speech/json/SpeechletRequestEnvelope.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ public class SpeechletRequestEnvelope<T extends SpeechletRequest> {
/**
* Returns a new builder instance used to construct a new {@code SpeechletRequestEnvelope}.
*
* @param <E> SpeechletRequest
* @return the builder
*/
public static <E extends SpeechletRequest> Builder<E> builder() {
Expand All @@ -87,6 +88,8 @@ private SpeechletRequestEnvelope(final Builder<T> builder) {
* the version of the request envelope
* @param session
* the session
* @param context
* the context
* @param request
* the speechlet request
*/
Expand Down
18 changes: 18 additions & 0 deletions src/com/amazon/speech/slu/ConfirmationStatus.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.amazon.speech.slu;


/**
* Indication of whether an intent or slot has been explicitly confirmed or denied by the user, or neither.
*
* Intents can be confirmed or denied using
* {@link com.amazon.speech.speechlet.dialog.directives.ConfirmIntentDirective}, or by indicating
* in the skill's configured dialog that the intent requires confirmation.
*
* Slots can be confirmed or denied using {@link com.amazon.speech.speechlet.dialog.directives.ConfirmSlotDirective},
* or by indicating in the skill's configured dialog that the intent requires confirmation.
*/
public enum ConfirmationStatus {
NONE,
CONFIRMED,
DENIED
}
32 changes: 28 additions & 4 deletions src/com/amazon/speech/slu/Intent.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@
* @see com.amazon.speech.speechlet.IntentRequest#getIntent()
*/
public final class Intent {

private final String name;
private final ConfirmationStatus confirmationStatus;
private final Map<String, Slot> slots;

/**
Expand All @@ -70,6 +72,9 @@ public static Builder builder() {
*/
private Intent(final Builder builder) {
name = builder.name;

confirmationStatus = builder.confirmationStatus;

slots = Collections.unmodifiableMap(builder.slots);
}

Expand All @@ -82,8 +87,10 @@ private Intent(final Builder builder) {
* the slots associated with the intent
*/
private Intent(@JsonProperty("name") final String name,
@JsonProperty("slots") final Map<String, Slot> slots) {
@JsonProperty("confirmationStatus") final ConfirmationStatus confirmationStatus,
@JsonProperty("slots") final Map<String, Slot> slots) {
this.name = name;
this.confirmationStatus = confirmationStatus;

if (slots != null) {
this.slots = Collections.unmodifiableMap(slots);
Expand Down Expand Up @@ -122,26 +129,43 @@ public Slot getSlot(final String name) {
return slots.get(name);
}

/**
* Returns the confirmationStatus associated with this request.
*
* @return the confirmationStatus
*/
public ConfirmationStatus getConfirmationStatus() {
return confirmationStatus;
}

/**
* Builder used to construct a new {@code Intent}.
*/
public static final class Builder {
private String name;
private final Map<String, Slot> slots = new HashMap<>();

private Builder() {
}
private ConfirmationStatus confirmationStatus;

public Builder withName(final String name) {
this.name = name;
return this;
}

public Builder withConfirmationStatus(final ConfirmationStatus confirmationStatus) {
this.confirmationStatus = confirmationStatus;
return this;
}

public Builder withSlots(final Map<String, Slot> slots) {
this.slots.putAll(slots);
return this;
}

public Builder withSlot(final Slot slot) {
this.slots.put(slot.getName(), slot);
return this;
}

public Intent build() {
Validate.notBlank(name, "Intent name must be defined");
return new Intent(this);
Expand Down
30 changes: 24 additions & 6 deletions src/com/amazon/speech/slu/Slot.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@
* A {@code Slot} can be {@code null} if:
* <ul>
* <li>If what the user said is not in the definition, meaning that it does not match any predefined
* {@code Slot}, or no {@code Slot}s are defined for the Intent. Example:
* "place a reservation tonight"</li>
* {@code Slot}, or no {@code Slot}s are defined for the Intent. Example: "place a reservation
* tonight"</li>
* <li>If the {@code Slot} is specified in the domain definition, but the user did not provide
* enough information in their request. Example: "place a reservation."</li>
* </ul>
Expand All @@ -58,8 +58,10 @@
* @see Intent#getSlot(String)
*/
public final class Slot {

private final String name;
private final String value;
private final ConfirmationStatus confirmationStatus;

/**
* Returns a new builder instance used to construct a new {@code Slot}.
Expand All @@ -79,6 +81,7 @@ public static Builder builder() {
private Slot(final Builder builder) {
name = builder.name;
value = builder.value;
confirmationStatus = builder.confirmationStatus;
}

/**
Expand All @@ -89,9 +92,12 @@ private Slot(final Builder builder) {
* @param value
* the resolved value
*/
private Slot(@JsonProperty("name") final String name, @JsonProperty("value") final String value) {
private Slot(@JsonProperty("name") final String name,
@JsonProperty("value") final String value,
@JsonProperty("confirmationStatus") final ConfirmationStatus confirmationStatus) {
this.name = name;
this.value = value;
this.confirmationStatus = confirmationStatus;
}

/**
Expand All @@ -112,15 +118,22 @@ public String getValue() {
return value;
}

/**
* Returns the confirmationStatus for this {@code Slot}.
*
* @return the confirmation status
*/
public ConfirmationStatus getConfirmationStatus() {
return confirmationStatus;
}

/**
* Builder used to construct a new {@code Slot}.
*/
public static final class Builder {
private String name;
private String value;

private Builder() {
}
private ConfirmationStatus confirmationStatus;

public Builder withName(final String name) {
this.name = name;
Expand All @@ -132,6 +145,11 @@ public Builder withValue(final String value) {
return this;
}

public Builder withConfirmationStatus(final ConfirmationStatus confirmationStatus) {
this.confirmationStatus = confirmationStatus;
return this;
}

public Slot build() {
Validate.notBlank(name, "Slot name must be defined");
return new Slot(this);
Expand Down
10 changes: 9 additions & 1 deletion src/com/amazon/speech/speechlet/Directive.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@

package com.amazon.speech.speechlet;

import com.amazon.speech.speechlet.dialog.directives.ConfirmIntentDirective;
import com.amazon.speech.speechlet.dialog.directives.ConfirmSlotDirective;
import com.amazon.speech.speechlet.dialog.directives.DelegateDirective;
import com.amazon.speech.speechlet.dialog.directives.ElicitSlotDirective;
import com.amazon.speech.speechlet.interfaces.audioplayer.directive.ClearQueueDirective;
import com.amazon.speech.speechlet.interfaces.audioplayer.directive.PlayDirective;
import com.amazon.speech.speechlet.interfaces.audioplayer.directive.StopDirective;
Expand All @@ -27,7 +31,11 @@
@JsonSubTypes({
@JsonSubTypes.Type(PlayDirective.class),
@JsonSubTypes.Type(StopDirective.class),
@JsonSubTypes.Type(ClearQueueDirective.class)
@JsonSubTypes.Type(ClearQueueDirective.class),
@JsonSubTypes.Type(DelegateDirective.class),
@JsonSubTypes.Type(ElicitSlotDirective.class),
@JsonSubTypes.Type(ConfirmSlotDirective.class),
@JsonSubTypes.Type(ConfirmIntentDirective.class),
})
public abstract class Directive {
}
64 changes: 60 additions & 4 deletions src/com/amazon/speech/speechlet/IntentRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,46 @@
/**
* The request object containing an {@link Intent} for {@code SpeechletV2} invocation.
*
* @see SpeechletV2#onIntent(SpeechletRequestEnvelope)
* @see SpeechletV2#onIntent
*/
@JsonTypeName("IntentRequest")
public class IntentRequest extends CoreSpeechletRequest {

/**
* When a skill has a managed dialog configured, this field indicates the current dialog state
* for the intent request.
*/
public enum DialogState {
/**
* Indicates this is the first turn in a multi-turn dialog. Skills can use this state to
* trigger behavior that only needs to be executed in the first turn. For example, a skill
* may wish to provide missing slot values that it can determine based on the current user,
* or other such session information, but doesn't wish to perform that action for every turn
* in a dialog.
*/
STARTED,

/**
* Indicates that a multi-turn dialog is in process and it is not the first turn. Skills may
* assume that all of the required slot values and confirmations have not yet been provided,
* and react accordingly (for instance by immediately returning a response containing a
* {@link com.amazon.speech.speechlet.dialog.directives.DelegateDirective}).
*/
IN_PROGRESS,

/**
* Indicates that all required slot values and confirmations have been provided, the dialog
* is considered complete, and the skill can proceed to fulfilling the intent. Nevertheless,
* the skill may manually continue the dialog if it determines at runtime that it requires
* more input in order to fulfill the intent, in which case it may return an appropriate
* {@link com.amazon.speech.speechlet.dialog.directives.DialogDirective} and update slot
* values/confirmations as required.
*/
COMPLETED;
}

private final Intent intent;
private final DialogState dialogState;

/**
* Returns a new builder instance used to construct a new {@code IntentRequest}.
Expand All @@ -49,6 +84,7 @@ public static Builder builder() {
private IntentRequest(final Builder builder) {
super(builder);
this.intent = builder.intent;
this.dialogState = builder.dialogState;
}

/**
Expand All @@ -62,32 +98,47 @@ private IntentRequest(final Builder builder) {
* the locale of the request
* @param intent
* the intent to handle
* @param dialogState
* the dialog state
*/
protected IntentRequest(@JsonProperty("requestId") final String requestId,
@JsonProperty("timestamp") final Date timestamp,
@JsonProperty("locale") final Locale locale, @JsonProperty("intent") final Intent intent) {
@JsonProperty("locale") final Locale locale,
@JsonProperty("intent") final Intent intent,
@JsonProperty("dialogState") final DialogState dialogState) {
super(requestId, timestamp, locale);
this.intent = intent;
this.dialogState = dialogState;
}

/**
* Returns the intent associated with this request. For a new session, the {@code Intent} passed
* as a parameter is the one that caused the Alexa skill to be started. It can be an
* {@code Intent} that is relevant to the skill and provides information on what to do, or it
* can simply be the {@code Intent} resulting from the user saying
* "Alexa, start &lt;Invocation Name&gt;".
* can simply be the {@code Intent} resulting from the user saying "Alexa, start &lt;Invocation
* Name&gt;".
*
* @return the intent to handle
*/
public Intent getIntent() {
return intent;
}

/**
* Returns the isInDialog value associated with this request.
*
* @return the isInDialog value
*/
public DialogState getDialogState() {
return dialogState;
}

/**
* Builder used to construct a new {@code IntentRequest}.
*/
public static final class Builder extends SpeechletRequestBuilder<Builder, IntentRequest> {
private Intent intent;
private DialogState dialogState;

private Builder() {
}
Expand All @@ -97,6 +148,11 @@ public Builder withIntent(final Intent intent) {
return this;
}

public Builder withDialogState(final DialogState dialogState) {
this.dialogState = dialogState;
return this;
}

@Override
public IntentRequest build() {
Validate.notBlank(getRequestId(), "RequestId must be defined");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.amazon.speech.speechlet.dialog.directives;

import com.fasterxml.jackson.annotation.JsonTypeName;

/**
* A Directive which a skill may return to indicate that the skill is asking the user to
* confirm or deny the overall intent. The skill must also provide output speech for the request.
* If the user confirms the intent, subsequent requests to the skill for the same dialog
* session will have a confirmationStatus of
* {@link com.amazon.speech.slu.ConfirmationStatus#CONFIRMED} for the intent; if the user denies
* the value, the confirmationStatus will be
* {@link com.amazon.speech.slu.ConfirmationStatus#DENIED}.
*
* When a user confirms the intent, it is expected that the skill will then try to fulfill the
* intent. When a user denies the intent, or the user confirms the intent but the skill is unable
* to fulfill it, the skill may either end the session or give the
* user the opportunity to (re-)confirm or change one or more slot values via a sequence of
* {@link ConfirmSlotDirective} and/or {@link ElicitSlotDirective}. In this case, the skill
* should use {@link #setUpdatedIntent} to clear any values or confirmation statuses as
* necessary.
*
* @see DialogDirective#setUpdatedIntent
*/
@JsonTypeName("Dialog.ConfirmIntent")
public class ConfirmIntentDirective extends DialogDirective {
}
Loading

0 comments on commit 40ab702

Please sign in to comment.