Adding slot changing the intent - ibm-watson

I have created a dialog which checks for some Intent and entity to trigger the response, I have also added slots to capture the missing entities. But when user enter the slot value it changes the intent thus causing change in final response. I have tried adding context variable also and deleting it after response but it gets deleted before response and I am getting empty context variable in response.
Like I have added a slot for capturing missing color values in an Intent say 'looking' and color values are like 'I, G, H' and there's also an Intent let's say Goodbye which is also trained for values like 'G or H'. So, when a user fills the slot value with 'G or H' it also overrides the previous intent 'looking' to 'Goodbye' and my final response value changes. What is the best way to handle this kind of flow?

The current intent is based on the latest utterance by the end user. So when someone types in a follow up to a slot, the intent will change and this is intended.
A common confusion is that this impacts the dialog tree. Because when you test it in "Try it out" you see the intent change. Unless your dialog tree is explicitly looking for it after the slot, then it has no impact what-so-ever.
If you do need it to stay the same, then you can send back the intent object in your context. This will disable Watson Assistant from trying to guess the intent.
The danger here is you need to be mindful that what you send back might not reflect what the user has entered. For example, they may ask something that has to trigger the handler of a slot. Doing this will disable that ability.

Related

Alexa Skill - Programmatically Enable/Disable Slot Matching

I have an Alexa skill that at one point asks for names, and at another point asks for numbers. The names are being mapped to a slot of type AMAZON.FirstName and the numbers to a slot of type AMAZON.NUMBER. The problem is that Alexa is aggressively interpreting even number values as names. (e.g. Saying "eight" is likely to be cast as the name "Tate.")
From what I can tell, Dialog Delegation is useful only if you know exactly how many of each type you need to capture. But in my case there are a variable number of times I will need to capture a name, so I can't just fill that slot once and be done with it.
Ideally I would like a way to programmatically turn the slots on and off. So when I prompt the user for a name, any utterance CAN ONLY BE MAPPED TO A NAME or else rejected (obviously HELP and EXIT, etc would still work). And then when I ask for a number, any utterance WILL ONLY BE MAPPED TO A NUMBER, it won't even try to cast it into the type AMAZON.FirstName.
Is there any way to achieve that? Or are there any other workarounds for scenarios like this?
I'd change the approach you're taking. You have a great tool for validation before even getting to code itself. Click the slot you're trying to validate, then click on the "validations" tab.
Right there, you can add either one or two rules. If you do one, you can add the "not within a set of values" and you can type "one", "two", etc. in order to avoid getting those numeric values inside your name slot.
If you take the two rule validation, you will need to add a "Value within slot types' slot values". That way, you will only accept values inside the AMAZON.FirstName slot type.
You don't really need to enable/disable a slot, you can simply take both in the same utterance. Just make sure you're validating your slots properly and that way you'll avoid unvalid data from getting into your skill :)
Read more: https://developer.amazon.com/es-mx/docs/custom-skills/validate-slot-values.html

How to make Alexa prompt me for additional information if I missed a parameter in my utterance?

How can I make Alexa prompt me (e.g. “You want weather for which city again?”) if I missed a parameter (slot i.e. city_name) in my utterance?
I am making a skill which tells me weather of a city. I have utterances and it works alright, but when I don't define a city name (city_name is also my only slot in my intent) then it directly goes to stop intent and gives my message "Alexa cannot help you with this".
In my slot (city_name) I've even checked "Is this slot required to fulfill the intent?" and have filled Alexa prompts and user utterances but still it doesn't work.
Use alexa dialogs. Dialog automatically fills all the required slots by reprompting the user for the slot value that he has missed. A dialog has 3 states, STARTED, IN_PROGRESS, COMPLETED. Dialog state will be completed only if you have all the required slot values filled. Watch the tutorial here
You can use different Dialog interface directives to ask the user for the information you need to fulfill their request. When ever there is an user interaction with your skill, you will get a request at your backend with the mapped intent and filled(or unfilled) slots. Even if you use dialog model and has filled in all the utterances for each slot, you will have to respond back with an appropriate directive to continue.
There are three ways in which you can handle a dialog model.
1. Delegating to Alexa
You can use the Dialog.Delegate directive to let Alexa determine the next step in the dialog and uses the prompts that you have defined in the dialog model to elicit slot values, confirm slot values, or confirm the entire intent.
If you have unfilled slots just return a delegate directive, Alexa will use the prompts defined in the interaction model to fill that slot. As long as the dialogState property is not COMPLETE you can continue delegating to Alexa.
Once the conversation is complete, the incoming IntentRequest has a dialogState of COMPLETED. All required information is now available in the intent's slot values.
Note: With Dialog.Delegate directive you cannot send outputSpeech or reprompt from your code. Instead those defined in interaction model will be used. And the COMPLETED status is only possible when you use Dialog.Delegate.
2. Control the Dialog
In each turn of the conversation you can take the control and ask for what you need rather than delegating it to Alexa. This is useful especially when you want slots to be filled a particular order or you want to confirm slots as you go or your slot's "mandate" property is dynamic in nature and so on.
You can use Dialog.ElicitSlot directive to ask for a particular slot, Dialog.ConfirmSlot to confirm a particular slot and Dialog.ConfirmIntent to confirm an intent itself.
3. Combining both
When you receive an intent request you can return a delegate directive or any other directive as you wish. Even if you delegate, at any point you can take over the dialog rather than continuing to delegate to Alexa.
More on the different directive here
Sample Interactions:
1. Using delegate directive here
2. Using ElicitSlot directive here
3. Using ConfirmSlot directive here
4. Using ConfirmIntent directive here

How to fire fallbackIntent even if user's dialogue fall into some other intent

I am developing an app and everything is working good. One condition are there where I have set the utterances but if user is speaking something else, I am throwing it to the fallbackIntent. One of my utterance is {name} so user can speak any name. But I have define range of name as well that user is allowed only these names. So my problem is if the user is choosing defined names, everything working great and if user said something else like what is weather of chicago, it is going to fallbackIntent as well but the issue is if user speak some name which is not in the list, then too it is coming into defined intent. What i want that if user speak something which is correct but not in my defined name then too redirect it to the fallbackIntent. Is there any way I can call intent in giving condition? I am using php.
When you define a custom slot, Alexa take it's values as samples. So values which are not in the slot-value-list will also be passed to you. And with respect your intent, those slot values are valid, hence that intent is triggered.
The solution is to validate the slot values at your backend and return an appropriate response.
In your case, if u get any other names other than those you have defined, respond back with an error or give FallbackIntent's response.
When you create a custom slot type, a key concept to understand is
that this is training data for Alexa’s NLP (natural language
processing). The values you provide are NOT a strict enum or array
that limit what the user can say. This has two implications
1) words and phrases not in your slot values will be passed to you,
2) your code needs to perform any validation you require if what’s
said is unknown.

Re-using entities in Watson Assistant results in automatically filled context variables

So to my understanding, entities are supposed to be re-used amongst different slots to optimize for the fact that you may want to accept a user input info for similar data types i.e. two separate slots "what is your household income", "what is your spouse's household income" would both use the #sys-currency entity.
In my current dialog flow, I have two child nodes each with one slot that checks for the sys-currency entity type. I'm using two different context variables however to set the slot.
The problem is that after the user inputs an answer for the first child node ('household income'), the context variable is then set for the following one as well. They have the same entity, but different context variables. To my understanding, this shouldn't be happening. I can confirm the node is processed, but it immediately skips the prompt as if it's already been filled and delivers the response in the node.
You are telling it to jump to the next slot and look for that entity. The user does not get the chance to input anything because their last message contained that entity. You should try jump to and wait for user input
If one node is giving a jump-to to the other, this will happen. The reason is because the intent and the entities found on the user input will be evaluated against all nodes from the flow until a new "wait for user input", where they will be changed.
In those situations, i normally create a new entity with a value that would never be found (like 389jd8239d892d8h89hf32hdsa8hdj3), to force every input into the not-found node of the slot, and there i use the entity necessary, in this case it would be the #sys-currency. This way the question will aways show, even if in a previous input the user typed a valid currency. To me it's useful when dealing with flows that use a lot of #sys-numbers/#sys-currency/#sys-date, and there isen't a lot of text to use to differenciate the values.
Another option would be to remove the slot and use a single node, with his own flow to get the answer. Personally i prefer to use slots, since it's easy to treat multiple possibilities. I would even put both questions on the same node, just using conditions to check if the slot should be evaluated or not.
I have searched for a way to clear the intent/entity recognized from the input in a previous node, but at no success.
So... I know this is a year and 3 months late, but I'll provide an answer in case anyone else is experiencing this issue.
The root cause is the "Divorce - Household Income" node sets the input.text to a value that the #sys-currency entity matches so any nodes you jump to that matches based on #sys-currency will automatically have their context variables set to the input.text without prompting the user.
Unfortunately, I haven't seen any documentation from IBM that allows you to set the input.text to null.
To solve this issue, you need the user to provide some other value that won't match #sys-currency.
Thankfully, the solution is simple to implement and users may actually prefer you follow my outline below.
Simply have your "Divorce - Household Income" node jump to a node that asks them to confirm their entry. Options such as Yes and No are perfect since they'll set input.text to "Yes" or "No", respectively.
Finally, jump to the "Divorce - Spouse Income" node. Since #sys-currency won't match the user's input.text, the node will properly prompt the user to fill the $spouse_annual_income slot.

Elicit Slot from within HelpIntent in Alexa

I have implemented a multi-turn dialog for Alexa. The Help-Intent provides different Help-Texts depending on the state of the dialog. After the User has triggered the HelpIntent and was presented the Help-Text, I want to elicit a specific slot with the ElicitSlotDirective
Now this seems to be not supported, since you can only elicit slots of the current intent, and the HelpIntent does not have slots.
https://github.com/alexa/alexa-skills-kit-sdk-for-nodejs/issues/162
My question now is: How can I return to my multi-turn dialog and elicit a specific slot after the user triggered the HelpIntent?
You can now use intent chaining to elicit a slot from a different Intent. For example:
.addDirective({
type: 'Dialog.ElicitSlot',
slotToElicit: 'drink',
updatedIntent: {
name: 'OrderIntent',
confirmationStatus: 'NONE'
}
})
See this blog post.
The documentation states that:
Implementing the built-in intents is recommended, but optional.
I recommend that you define your own HelpIntent with overlapping utterances to the AMAZON.HelpIntent, but with your needed Slot types.
In this case, your service receives an IntentRequest for MyHelpIntent, even though these phrases overlap with the built-in AMAZON.HelpIntent.
The documentation also states, that this practice is not recommended, because the built-in intent may have a better coverage of sample utterances. It states that it is better practice to extend the built-in Intents. But (stupid enough from Amazon), the HelpIntent does not support Slots. So the only way would be a custom Help Intent.
I don't see a way to use Dialog Directives with the built-in Intents.
Here's a convoluted workaround that might work (there's no straight forward way right now, Nov 2018):
On every loop of the multi-turn dialog save your dialog based intent in the session attributes (the whole intent object, you can use the intent.name as key)
On every triggered intent (even HelpIntent) save the intent name in a lastIntent session attribute (to keep track of the previous intent name)
User triggers help and you're now in the HelpIntent. After you provide your help message append a question in the end that will cause the user to say something that will trigger your dialog based intent again
Do the following steps when you are in the dialog based intent and only if the lastIntent was HelpIntent (the one in the previous step):
Load the most recent intent data from the session attributes and, in it, delete the slot value and resolutions of the slot you want to elicitate (alternatively if you want to start from scratch you can delete the remaining slot values too, up to you)
Replace the current intent with the modified intent of the previous step
Emit a DialogDelegate with the current intent (your model needs to flag the slot you want to elicitate with elicitationRequired set to true)

Resources