How do i stop my Watson Assistant from auto-correcting the user input - ibm-cloud

Can anyone help me solve this issue
The screenshot attached below is self explanatory
It is auto-correcting sufyan to Susan
The value for the context variable is
"<? input.text.substring(0, 1).toUpperCase() + input.text.substring(1) ?>"
The motive here is to simply convert lowercase name sufyan to Sufyan
or for that case any Indian name.
But the auto-correct has now become a hindrance.
I want the assistant to interact with the user in the later part using his/her name.

You can configure autocorrection in your bot settings.

Along with Henrik’s answer, it’s good to learn about fuzzy matching in Watson Assistant as it runs before autocorrection
How is spelling autocorrection related to fuzzy matching?
Fuzzy matching helps your assistant recognize dictionary-based entity mentions in user input. It uses a dictionary lookup approach to match a word from the user input to an existing entity value or synonym in the skill's training data. For example, if the user enters boook, and your training data contains a #reading_material entity with a book value, then fuzzy matching recognizes that the two terms (boook and book) mean the same thing.
When you enable both autocorrection and fuzzy matching, the fuzzy matching function runs before autocorrection is triggered. If it finds a term that it can match to an existing dictionary entity value or synonym, it adds the term to the list of words that belong to the skill, and does not correct it.
Check the complete documentation here before turning of autocorrection

You can use the following context variable:
"<? input.original_text.substring(0,1).toUpperCase() + input.original_text.substring(1) ?>"

Related

Getting the user's name without directly asking for it (Watson Assistant)

I'm creating a chatbot for fun and want to implement something to collect the user's name, but only if he says something like "my name is ..." or close to that; the intention of giving the name would come from the user, the bot won't ask for it, maybe only suggest it. Kind of like in Google Assistant, I think. So, it could be given at any time the user wants.
My idea is:
1st create an intent with different ways the user would tell his name to the bot (like in the example above).
2nd use slots and, if the intent is detected, save it as a variable. So far, I've managed.
3rd is the part that I'm stuck in, since it's only an idea and I don't know how I'd do it. Before saving the whole text as a variable, I'd like to delete the part that's included in the intent (my name is) and save only the rest in the variable. So, for example, the user says "my name is XXX"; the command deletes the "my name is" part and saves only "XXX" in the $name intent.
I don't know if this'd be possible, since I don't know coding. I used some special syntax before, like to capitalize the first letter of some other variable, but I don't really know how to use the JSON editor.
Is my idea viable? I don't know how I'd delete the intent corresponding portion and save only the remaining part as the intent. Dunno what would be the command for that, nor where I'd write it.
You can suggest something else if you have an idea.
Last thing, I'm created the skill in portuguese, so there's no access to the #sys-person entity.
Thanks for reading.
I use portuguese skills and face the same issue. I see two solutions, althougt they are not perfect:
Using intents:
When the intent is identified, the bot asks the name again, telling the user that he should only say his name, e.g without "my name is", then store the whole input on a context variable, using:
<? input.text ?>
For embedding such logic inside slots, you probaly will need to use digressions.
But, this is boring to the user.
Using entities:
Entities identification carries along they start and end position in the input text, but intents not. With this, is possible to slice the input, cutting the entity:
<? input.text.substring(entities.name.location[1], input.text.length()) ?>
Entites would be "My name is", "People call me", "I'm called", "I'm baptized", "I was baptized".
So, "Hello, my name is Gustavo", would be cut after "my name is" ending, resulting in "Gustavo". Additional input in the beggining is ignored, but problems arrise with additional input after the name. Also, you need to define more "my name is" like entities, likely all possibilities, than would need if using intents, cause even with fuzzy matching, entities identification doesn't take in account synonymus and similar meaning words.
https://cloud.ibm.com/docs/assistant?topic=assistant-dialog-methods#dialog-methods-strings-substring
https://cloud.ibm.com/docs/assistant?topic=assistant-expression-language#expression-language-access-entity

Is it possible to use INTENT instead of STRING as List Title in Google Action?

Some Background:
I use Lists a lot for a Google Action with a NodeJS fulfillment backend. The Action is primarily Voice-based. The reason for using List is that I can encode information in List's key and use it later to make a decision. Another reason is that Google Assistant will try to fuzzy match the user's input with the Title of the List's items to find the closest matched option. This is where thing's get a bit hard for me. Consider the following example:
{
JSON.stringify(SOME_OBJECT): {
title: 'Yes'
},
JSON.stringify(ANOTHER_OBJECT): {
title: 'No'
}
}
Now if I say Yes / No, I can get the user's choice and do something with information stored as stringified JSON in the choice's Key.
But, the users may say Sure or Yup or OK as they basically mean the same thing as saying Yes. But as those words don't match Yes, Google Assistant will ignore the "Yes" option. But all of these words belong to the smalltalk.confirmation.yes built-in intent. So, if I could use this intent instead of hardcoding the string Yes then I would be able to capture all of the inputs that mean Yes.
I know I could do this with a Synonyms list or Confirmation intent. But they also have some problems.
Using Synonyms would require me finding every word which is similar. Besides, I would also need to localize these synonyms to all the supported language.
With Confirmation intent, I won't be able to show some information to the user before asking them to choose an option. Besides, it also doesn't support encoding the options as I can do in List's key.
So, List is a good choice for me in this case.
So, is there any way to leverage the built-in intents for this purpose? What do you do in this situation?

Using context variables to write the user's car registration

In watson-conversation, I have reached a point where I ask the user their car number (registration), which follows this format: 0000BBB (4 numbers, 3 letters).
I want to type that to the user like:
User: "My car id is 0123asd"
Watson: "Okay so your car id is this one: 0123asd"!
I have tried defining an entity #carId with some examples, but every time I input something with that format (0000BBB), it shows "irrelevant".
If the chat detects #carId, respond with Okay so this is your carId! #exampleCarId (I have some examples like 5487qwe, or 8521rty, I thought the machine learning below that would learn the "pattern").
And my #carId has these examples:
I know I am missing something! Do I need to code anything? I think it's not necessary. I tried to save it on a sys-number but it does not work as it is not a "number".
Most developers would consider he car ID an entity (denoted by #). IBM Watson Assistant allows to define so-called dictionary-based entities. One form of such an entity is pattern-based. Thus, you would define a pattern of 4 digits and 3 letters.
You could have an intent (denoted by #) that identifies that a user inputs the car ID. In the dialog node you could match against the intent and then assign the matched entity for the actual ID to a variable.
The linked documentation has examples.

IBM Watson Assistant: Chatbot Entity Confusion over regular expression

I have an entity called "#material_number" in which two values are stored.
First value is "material_number1" with the pattern (\d{3}).(\d{3})
The second value is "material_number2" with the pattern (\d{3}).(\d{3}).(\d{3})
When the user enters a material number, I store the value with a context variable called "$materialnumber" and I set the value of this variable to "?#material_number.literal?". And at the end the bot responds "Oh okay, the material number is $materialnumber."
The problem is that when the user enters a material number like "123.123.123", the bot thinks that the material number is "123.123". Basically it neglects the last three digits and prompts back "Oh okay, the material number is 123.123".
What can I do in order to fix this confusion?
I quickly tested this and there are two problems. First, the dot (. is a special wildcard and needs to be escaped. Second, Watson Assistant does not support the full regex options and seems to match both numbers when typing in the longer number.
You can simply escape using a \ and change your definition or use mine:
num1: (\d{3}\.){1}\d{3}
num2: (\d{3}\.){2}\d{3}
Because of the trouble with the regex evaluation I solved that in the expression itself. Watson Assistant holds the longer match as second value (if matched). The following expression looks if the long number, material_number2, has been matched, then extracts the correct value for it. It assumes that the shorter (incorrect) match is stored first.
{
"context": {
"materialnumber": "<? #matrial_number:matnum2 ? entities.material_number[1].literal : entities.material_number[0].literal ?>"
}
}

Recognize undefined Entities in Watson Conversation

Please, I wanted to know if it is possible to catch different entities on Watson conversation without defining their values.
For example, I am working on a Mobile up for room booking in my company and I can't define all the room's names so I want that my Bot recognize the name just according to the used pattern for example
"Book #room for tomorrow"
and whatever I put in place of #room it takes it as a room name.
thank you
Its now available check out https://console.bluemix.net/docs/services/conversation/entities.html#pattern-entities
A pattern must be entered as a regular expression in the field.
For instance internationalPhone: ^(\(?\+?[0-9]*\)?)?[0-9_\- \(\)]*$, e.g., +44 1962 815000
EDIT: The solution below still works but right now the pattern entities as discussed by Dudi are more systematic solution. Leaving this here for legacy reasons.
Right now the regexp support inside Watson Conversation Service is probably the est bet.
For your particular example, you can use the following expression inside the dialog node condition:
input.text.matches('^[bB]ook[^\w]+(\w+).+ (tomorrow|today)$')
and inside that node you can add the following regexp to node context to extract the second word (or the word after "Book") to a variable:
"room" : "<? input.text.extract('^[bB]ook[^\\w]+(\\w+).+ (tomorrow|today)$',1) ?>"
(note that in context unlike in conditions you need to actually escape \ with another \)
This will match inputs such as "book bathroom for today" or "book r101 for tomorrow".
A good place where you can try your regexp expressions is https://regex101.com/