I am using IBM Watson Assistant for a chatbot. I have a dialog node with two slots. The first slot works fine. The node gets triggered and the bot asks for the first slot, since it is not present.
Then I would like to have the bot asking for the second slot. And the answer given should be stored in a $variable. I tried to achieve this with input.text, because I want to store every kind of input given there.
But instead of asking for the second slot the bot skips it and stores the answer given in slot one in the slot two $variable as well.
I guess it's because the bot also checks if input.text is present in slot one. To make it clear, I have not activated the 'prompt for everything' option.
How can I overcome this?
I am sure these screenshots of my test environment will make everything more clear:
This is because input.text as a check matches all input, so no matter what you enter your second slot will always be satisfied.
The way slots work is that it doesn't matter in which order the information is given or how much is given.
For Example: Say I have an ordering system looking for 'product', 'quantity', and 'delivery date'
The request 'I want spoons for the 3rd Feb'
Then two of the slots 'product' and 'delivery date' are satisfied and the output response will be for the prompt for the missing 'quantity' slot.
In your case you need to determine what information you are trying to gather. Is there an entity or an intent that is going to uniquely match the input. If so then you could use a slot. As a brute force match you can make the condition for the second slot more complex.
For example when looking for confirmation of an order you can add in the condition, which only triggers when all above slots have been completed, and you are looking to confirm whether you collected the instructions correctly.
(#yes || #no) && slot_in_focus
If this kind of approach doesn't fit your application then you should gather this information after the node for the slots.
Related
I'm using Watson Assistant Chatbot..I want to save a variable from the user input by enabling Slots and system entities like #sys-number.. I can save number by choosing check for #sys-number, or saving date by choosing check for #sys-date... But for text/characters I can't find something like #sys-text or #sys-char..
I tried to save text while check for #sys-number, but the answer is not saved into the variable and the question keep repeating in th chatbot console.
So, how can I use Slots to save text from user input, I mean what should I put in "check for", please?
Thanks,
Numbers are always numbers, no matter your language and context. Dates are always dates as well.
However, "texts" can mean many different things, and they depend on context. That's why you need to create a separate entity for each meaning in your context.
For IBM Watson Assistant, there is no reason to detect "any text" unless that text means something in your context.
Supposing you want to detect the word "smartphone". For Assistant, there is no reason to detect this word if it doesn't relate to any entity.
So, you need to create an entity (e.g. "#Product") and then give it a value named "smartphone". Then, whenever a user types "smartphone" in your Chatbot, Assistant will be able to recognize "#Product:smartphone".
In your Slots, in the "Check for" field, you can put "#Product". It means that if Chatbot doesn't detect any #Product (e.g. "smartphone"), it should repeat the question until it finds a valid product.
I have a stock agent which is created in the end of my production line. My products are characterized by their model. I'm trying to create a logic to take out the products from this stock agent when they are to be delivered to the client. This delivery is controlled by an excel sheet and I'm taking the information through a SQL code. However, I was not able to find the right code to take out the products which are to be delivered. My agent population is called ProdutoStock and it's located in my main screen.
I have tried: Main.remove_ProdutoStock() but i couldn't figure out the arguments that i need for this function, since i have to take out of the agent a specific number of agents and also of a specific model.
So, I decided to create a wait block and use the free function to free the specific agents i wanted main.waiting_delivery.free() but i also can't figure out the necessary arguments for this function.
Would someone have any idea how I can take out of my agent/line the products that I need to deliver for my client (considering quality and also model)? This code is not being typed into my main screen.
the argument of the free method is the agent itself.
So you have to do main.waiting_delivery.free(yourAgent);
If you want to free the last agent that entered the wait block:
if(main.waiting_delivery.size()>0)
main.waiting_delivery.free(main.waiting_delivery.get(0));
If you want to free agents following a certain condition
List <YourAgent> theAgents=findAll(main.yourAgentPopulation,a->a.condition==true);
for(YourAgent a : theAgents){
main.waiting_delivery.free(a);
}
I want to show a different option to the user in workflow through input node, depending upon whether the user has modified the record or not.
Problem is if I would use a condition node with custom class to detect whether object has been modified by some person or not in between the workflow process then as soon as the person clicks on route workflow the save is automatically called and isModified() flag gets false, How do I get in condition node whether some person has modified the record or not.
I have to show different options to the user if he has modified and different option on routing workflow if he have not modified.
Sounds to me like you need to enable eAudit on the object and then to check whether eauditusername on the most recent audit record for that object bears the userid of the current user.
It's a little hokey and tempts fate, but if your condition node is early in the workflow's route when this button is pressed, you could try and check to see if the changedate on the object (assuming you are working with one of the many objects that has one) is within the last 5 seconds. There is a gap where the record could be routed twice within a few seconds, but the gap is fairly hard to hit. There is also a gap where if the system slows down at that point and takes more than 5 seconds to get to and run your condition, then it would appear to be not modified. You can play with the delay to find a sweet spot of the fewest false positives and negatives.
I have two conversation nodes defined. The first is triggered on conversation_start and asks the users's name. The second stores the user name from input.text in a context variable and asks if the user wants to take a brief survey or do something else. The second one never executes. What should the trigger be on the second one in order to advance the conversation? There is no intent or condition set yet. Basically, I just want to follow a string-of-pearls pattern where every question gets asked and let the user opt out of some of the questions.
there are two main ways to achieve this. The one I recommend is to create an intent for each possible way. For example, you could create an intent called #affirmative, with values like "Yes", "Yeah", "Sure", "Ok", etc. All you have to do is to create the intent and then use it in the condition field.
But you can also check the user's input directly, using input.text. For example, you could use input.text.toLowerCase() == 'yes' as the condition. Have in mind that this should only be used if you are controlling the input and only allowing a few possible values. If not, use an intent and let Watson Conversation handle the input parsing for you.
Another really cool feature that Watson Conversation provides that can benefit is you is to have a node with a condition like intents[0].confidence < 0.6 and a response like "Sorry, I didn't get that". That way you make sure your flow will only trigger a condition with a high confidence for the intent.
Hope it helps!
You can use the jump to function to route the system to arbitrary dialog_node - this is great for creating directed dialogs. So whenever you want to continue with the next question (user answered the previous question), you can use jump to from the node processing the answer to the previous question to ask the user another question (jump to the body part of the next dialog node asking new question).
Now for "get name" use case you want the second node gathering the name from the user input hanging off the conversation_start node. If the conversation encounters a node that has children, the processing of the next dialog round will start at the first child of this dialog node - this way the contextual dialogs are defined in the conversation.
Bluemix Conversation can be thought of as a state machine. Each transition is diagrammed in the tooling, but each node can only be triggered by a condition. So that if you're on a node asking a question, and the answer that comes back does not trigger one of the child nodes, the state will not transition to a child. Answers entered into a node are processed by Watson, who provides "intents", which are essentially keywords found in the sentence he just analyzed. So one way to advance the conversation is to match named "intents" using the # prefix to the trigger of in a child node. Another way it to match named "entities" using the # prefex, although it is less clear how Watson builds entities. The third way is to match context variables using the $ prefix and simple conditional operators such as ==. Context variables are entirely managed by you, the developer. You are allowed to set one context variable at each node. And then you can use it to trigger a child node. This appears to be a good approach to managing the type of conversation I want to implement. The fourth way is to use the previous parent node's input value using along with simple conditional operators.
I have a requirement to allow a user to specify the value of an InArgument / property from a list of valid values (e.g. a combobox). The list of valid values is determined by the value of another InArgument (the value of which will be set by an expression).
For instance, at design time:
User enters a file path into workflow variable FilePath
The DependedUpon InArgument is set to the value of FilePath
The file is queried and a list of valid values is displayed to the user to select the appropriate value (presumably via a custom PropertyValueEditor).
Is this possible?
Considering this is being done at design time, I'd strongly suggest you provide for all this logic within the designer, rather than in the Activity itself.
Design-time logic shouldn't be contained within your Activity. Your Activity should be able to run independent of any designer. Think about it this way...
You sit down and design your workflow using Activities and their designers. Once done, you install/xcopy the workflows to a server somewhere else. When the server loads that Activity prior to executing it, what happens when your design logic executes in CacheMetadata? Either it is skipped using some heuristic to determine that you are not running in design time, or you include extra logic to skip this code when it is unable to locate that file. Either way, why is a server executing this design time code? The answer is that it shouldn't be executing it; that code belongs with the designers.
This is why, if you look at the framework, you'll see that Activities and their designers exist in different assemblies. Your code should be the same way--design-centric code should be delivered in separate assemblies from your Activities, so that you may deliver both to designers, and only the Activity assemblies to your application servers.
When do you want to validate this, at design time or run time?
Design time is limited because the user can use an expression that depends on another variable and you can't read the value from there at design time. You can however look at the expression and possibly deduce an invalid combination that way. In this case you need to add code to the CacheMetadata function.
At run time you can get the actual values and validate them in the Execute function.