Skip to content

Instantly share code, notes, and snippets.

@germanviscuso
Created October 23, 2018 00:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save germanviscuso/df8ddd5bf1ec3eddc993900769ae141f to your computer and use it in GitHub Desktop.
Save germanviscuso/df8ddd5bf1ec3eddc993900769ae141f to your computer and use it in GitHub Desktop.
Alexa Skills Basics: Context Switch in Dialogue Management
{
"interactionModel": {
"languageModel": {
"invocationName": "pintor mágico",
"intents": [
{
"name": "AMAZON.CancelIntent",
"samples": []
},
{
"name": "AMAZON.HelpIntent",
"samples": []
},
{
"name": "AMAZON.StopIntent",
"samples": []
},
{
"name": "AMAZON.NavigateHomeIntent",
"samples": []
},
{
"name": "PintarHabitacionIntent",
"slots": [
{
"name": "habitacion",
"type": "AMAZON.Room",
"samples": [
"{habitacion}",
"para {habitacion}",
"para {un} {habitacion}",
"{quiero} pintar {habitacion}",
"{quiero} pintar {un} {habitacion}",
"{un} {habitacion}",
"habitación {habitacion}"
]
},
{
"name": "color",
"type": "AMAZON.Color",
"samples": [
"{color}",
"de {color}",
"color {color}",
"pintar {color}",
"pintar de {color}",
"pintar color {color}",
"píntalo {color}",
"píntalo de {color}",
"píntalo color {color}"
]
},
{
"name": "un",
"type": "tipoArticulo"
},
{
"name": "quiero",
"type": "tipoQuiero"
},
{
"name": "pintar",
"type": "tipoPintar"
}
],
"samples": [
"{quiero} {pintar}",
"{pintar}",
"me {pintar}",
"{pintar} {un} {habitacion}",
"{quiero} {pintar} {un} {habitacion} de color {color}",
"{quiero} {un} {habitacion} de color {color}",
"{quiero} {pintar} {habitacion} de color {color}",
"{quiero} {pintar} {un} {habitacion} de {color}",
"{quiero} {un} {habitacion} de {color}",
"{quiero} {pintar} {habitacion} de {color}",
"{quiero} {pintar} de color {color} {un} {habitacion}",
"{quiero} de color {color} {un} {habitacion}",
"{quiero} de color {color} {pintar} {habitacion}",
"{quiero} de {color} {pintar} {un} {habitacion}",
"{quiero} de {color} {un} {habitacion}",
"{quiero} de {color} {pintar} {habitacion}",
"{pintar} {un} {habitacion} de color {color}",
"{un} {habitacion} de color {color}",
"{pintar} {habitacion} de color {color}",
"{pintar} {un} {habitacion} de {color}",
"{un} {habitacion} de {color}",
"{pintar} {habitacion} de {color}",
"{pintar} de color {color} {un} {habitacion}",
"de color {color} {quiero} {un} {habitacion}",
"de color {color} {quiero} {pintar} {habitacion}",
"de {color} {quiero} {un} {habitacion}",
"de {color} {quiero} {pintar} {habitacion}",
"{pintar} {un} {habitacion} de {color}",
"{pintar} de color {color} {un} {habitacion}",
"{pintar} de {color} {un} {habitacion}",
"{pintar} {un} {habitacion} de color {color}",
"{quiero} {pintar} {un} {habitacion}",
"{quiero} {un} {habitacion}",
"{quiero} {pintar} {habitacion}",
"{pintar} un {habitacion}",
"{un} {habitacion}",
"{pintar} {habitacion}",
"{pintar} {un} {habitacion}",
"{quiero} {pintar} de color {color}",
"{quiero} de color {color}",
"{quiero} de {color} {pintar}",
"{pintar} de color {color}",
"de color {color} {quiero}",
"de {color} {quiero} {pintar}",
"de {color} {quiero}",
"{pintar} de color {color}",
"{pintar} de {color}",
"{pintar} de color {color}",
"{pintar} de {color}",
"color {color}",
"de color {color}",
"{color}"
]
},
{
"name": "ListarColoresIntent",
"slots": [],
"samples": [
"qué colores hay",
"qué colores tienes",
"colores soportados",
"gama de colores",
"paleta de colores",
"abanico de colores",
"cuál es la paleta de colores",
"cuál es la gama de colores",
"colores disponibles",
"dime la gama de colores",
"dime la paleta de colores",
"dime los colores",
"de que color se puede pintar ",
"qué colores hay disponibles"
]
}
],
"types": [
{
"name": "tipoArticulo",
"values": [
{
"name": {
"value": "las"
}
},
{
"name": {
"value": "los"
}
},
{
"name": {
"value": "la"
}
},
{
"name": {
"value": "el"
}
},
{
"name": {
"value": "una"
}
},
{
"name": {
"value": "un"
}
}
]
},
{
"name": "tipoQuiero",
"values": [
{
"name": {
"value": "vamos a"
}
},
{
"name": {
"value": "me gustaría"
}
},
{
"name": {
"value": "me gusta"
}
},
{
"name": {
"value": "querría"
}
},
{
"name": {
"value": "quisiera"
}
},
{
"name": {
"value": "quiero"
}
}
]
},
{
"name": "tipoPintar",
"values": [
{
"name": {
"value": "píntame"
}
},
{
"name": {
"value": "pintemos"
}
},
{
"name": {
"value": "colorea"
}
},
{
"name": {
"value": "pinta"
}
},
{
"name": {
"value": "pinte"
}
}
]
},
{
"name": "AMAZON.Color",
"values": [
{
"name": {
"value": "negra"
}
},
{
"name": {
"value": "roja"
}
},
{
"name": {
"value": "blanca"
}
}
]
}
]
},
"dialog": {
"intents": [
{
"name": "PintarHabitacionIntent",
"confirmationRequired": false,
"prompts": {},
"slots": [
{
"name": "habitacion",
"type": "AMAZON.Room",
"confirmationRequired": false,
"elicitationRequired": true,
"prompts": {
"elicitation": "Elicit.Slot.147269857970.1311113080241"
}
},
{
"name": "color",
"type": "AMAZON.Color",
"confirmationRequired": false,
"elicitationRequired": true,
"prompts": {
"elicitation": "Elicit.Slot.542396406661.65620125874"
}
}
]
}
]
},
"prompts": [
{
"id": "Elicit.Slot.147269857970.1311113080241",
"variations": [
{
"type": "PlainText",
"value": "¿Okey, de color {color} , pero cual habitación?"
},
{
"type": "PlainText",
"value": "¿Okey, pero cual habitación?"
}
]
},
{
"id": "Elicit.Slot.542396406661.65620125874",
"variations": [
{
"type": "PlainText",
"value": "¿Ya has dicho {habitacion} , pero de que color?"
},
{
"type": "PlainText",
"value": "¿Okey, pero de que color?"
}
]
}
]
}
}
//context switching demo
// check https://developer.amazon.com/ask-resources/guided/conversational-design-workshop/#/lessons/3tLzxbk5cva1-x9PNx_7RgpQm2H11_mg?_k=fq2azr
// and https://m.media-amazon.com/images/G/01/mobile-apps/dex/alexa/alexa-skills-kit/guide/Dialog-Management-Guide.pdf?aliId=26037891
const Alexa = require('ask-sdk');
const HELP_MESSAGE = 'Por favor dime: pinta, dime luego cual habitación y cuando te pregunte por el color interrúmpeme preguntando que colores hay';
const STOP_MESSAGE = 'Adios!';
const InProgressPintarHabitacionIntentHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest'
&& request.intent.name === 'PintarHabitacionIntent'
&& request.dialogState !== 'COMPLETED';
},
handle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
const {responseBuilder} = handlerInput;
const intent = request.intent;
return responseBuilder
.addDelegateDirective(intent)
.getResponse();
},
};
const CompletedPintarHabitacionIntentHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest'
&& request.intent.name === 'PintarHabitacionIntent';
},
handle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
const intent = request.intent;
const slotValues = getSlotValues(intent.slots);
const habitacion = slotValues["habitacion"].value;
const color = slotValues["color"].value;
let speechOutput = 'Okey! Ya te he pintado ' + habitacion + ' de color ' + color + '. Que lo disfrutes! Adiós!';
return handlerInput.responseBuilder
.speak(speechOutput)
.getResponse();
},
};
const ListarColoresIntentHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest'
&& request.intent.name === 'ListarColoresIntent';
},
handle(handlerInput) {
let speechOutput = "Me queda solo pintura negra, blanca, roja, verde y azul. ¿Cuál color quieres? "
return handlerInput.responseBuilder
.speak(speechOutput)
.reprompt(speechOutput)
.getResponse();
},
};
const HelpHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'LaunchRequest' ||
(request.type === 'IntentRequest'
&& request.intent.name === 'AMAZON.HelpIntent');
},
handle(handlerInput) {
return handlerInput.responseBuilder
.speak(HELP_MESSAGE)
.reprompt(HELP_MESSAGE)
.getResponse();
},
};
const ExitHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest'
&& (request.intent.name === 'AMAZON.CancelIntent'
|| request.intent.name === 'AMAZON.StopIntent');
},
handle(handlerInput) {
return handlerInput.responseBuilder
.speak(STOP_MESSAGE)
.getResponse();
},
};
const DialogManagementStateInterceptor = {
process(handlerInput) {
const currentIntent = handlerInput.requestEnvelope.request.intent;
if (handlerInput.requestEnvelope.request.type === "IntentRequest"
&& handlerInput.requestEnvelope.request.dialogState !== "COMPLETED") {
const attributesManager = handlerInput.attributesManager;
const sessionAttributes = attributesManager.getSessionAttributes();
// If there are no session attributes we've never entered dialog management
// for this intent before.
if (sessionAttributes[currentIntent.name]) {
let savedSlots = sessionAttributes[currentIntent.name].slots;
for (let key in savedSlots) {
// we override with a saved slot value only if the current intent does not
// have it and it's present in the saved slots
if (!currentIntent.slots[key].value && savedSlots[key].value) {
currentIntent.slots[key] = savedSlots[key];
}
}
}
sessionAttributes[currentIntent.name] = currentIntent;
attributesManager.setSessionAttributes(sessionAttributes);
}
}
};
function getSlotValues(filledSlots) {
const slotValues = {};
console.log(`The filled slots: ${JSON.stringify(filledSlots)}`);
Object.keys(filledSlots).forEach((item) => {
const name = filledSlots[item].name;
if (filledSlots[item] &&
filledSlots[item].resolutions &&
filledSlots[item].resolutions.resolutionsPerAuthority[0] &&
filledSlots[item].resolutions.resolutionsPerAuthority[0].status &&
filledSlots[item].resolutions.resolutionsPerAuthority[0].status.code) {
switch (filledSlots[item].resolutions.resolutionsPerAuthority[0].status.code) {
case 'ER_SUCCESS_MATCH':
slotValues[name] = {
synonym: filledSlots[item].value,
value: filledSlots[item].resolutions.resolutionsPerAuthority[0].values[0].value.name,
id: filledSlots[item].resolutions.resolutionsPerAuthority[0].values[0].value.id,
isValidated: true,
canUnderstand: true,
canFulfill: true,
};
break;
case 'ER_SUCCESS_NO_MATCH':
slotValues[name] = {
synonym: filledSlots[item].value,
value: filledSlots[item].value,
id: null,
isValidated: false,
canUnderstand: false,
canFulfill: null,
};
break;
default:
break;
}
} else {
slotValues[name] = {
synonym: filledSlots[item].value,
value: filledSlots[item].value,
id: filledSlots[item].id,
isValidated: false,
canUnderstand: false,
canFulfill: false,
};
}
}, this);
return slotValues;
}
const skillBuilder = Alexa.SkillBuilders.standard();
exports.handler = skillBuilder
.addRequestHandlers(
InProgressPintarHabitacionIntentHandler,
CompletedPintarHabitacionIntentHandler,
ListarColoresIntentHandler,
HelpHandler,
ExitHandler
)
.addRequestInterceptors(DialogManagementStateInterceptor)
.lambda();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment