Bot greeting stops working when adding QnA Maker resource - botframework

Using the awesome resources provided by Microsoft.
Following the documentation at https://learn.microsoft.com/en-us/composer/
Create Folder somewhere
Perform https://learn.microsoft.com/en-us/composer/setup-yarn in that folder
Perform https://learn.microsoft.com/en-us/composer/tutorial/tutorial-create-bot
Test in Emulator: Pressed Restart Conversation - New User ID: Works fine, responds with: Hi! I’m a friendly bot that can help with the weather. Try saying WEATHER or FORECAST.
Perform https://learn.microsoft.com/en-us/composer/tutorial/tutorial-add-dialog
Test in Emulator: Presents ”Let’s check the weather” som response på user input “weather”. Works fine.
Then create new Trigger with Dialog event and Dialog started and continue with: https://learn.microsoft.com/en-us/composer/how-to-add-qna-to-bot, enter the following in the settings
Please note that in order to use the Settings values, an extra “=”
has to proceed the id, e.g. “=settings.qna.knowledgebaseid”.
Please also not that in order to make this work in Europe, with our
“,” instead of “.” as decimal marker, the Threshold has to be set to
“float(‘0.3’)” in order to be evaluated as a float.
Make sure that the settings are accurate according to your QnA Base.
Please note that at this point the LUIS fiels are left mostly empty,
except for the values prefilled as described in
https://learn.microsoft.com/en-us/composer/how-to-add-qna-to-bot
No LUIS added at this point.
Restart bot
Click Test in Emulator
Press Restart Conversation - New User ID
Now there are three problems:
A. There is no longer any greeting phrase.
B. The first response from QnA maker results in a “The given key ‘stepIndex’ was not present in the dictionary.”. Then after this the QnA maker part works, but issue A and C are still present.
C. The weather regex does only trigger once if it is the first entry only, then at the second attempt or after entering something else, it fails to trigger.
Expected behavior:
When Press Restart Conversation - New User ID, the bot should greet
the user.
When the weather regex is the best choice it should trigger
The text “The given key ‘stepIndex’ was not present in the dictionary” should not be presented as the first response, instead the right reply should be presented based on the intent provided.

I`m a bit late to the game on this but I hit the exact same issue in composer and found the same problem. The suggested approach to use unknown intent in MS Docs does not work well. its really just a tutorial to get you up and running as quickly as possible, with no real thought beyond that - and as you point out, it easily gets stuck in an internal loop that prevents other intents from firing.
Assuming you are using Luis.ai, a "QnA intent recognised" should be added & a "duplicate intent recognised". this will make sure that automatic cross-training is implemented such that QNAmaker will know about Luis Questions and vice versa and they will not only understand their own questions but know to exclude the questions in the other approach. This will make for better training. However, depending on how similar questions are in both, they may both return matches of varying confidence anyway - this is what the "duplicate intent recognised" is for. It catches both before they execute their intents and implements checks for confidence against each and re-raises the event that wins out. Thus ensuring only one of the two is recognised and executed.

Related

MS Teams: how should we tell if an activity event comes from a bot?

we have a chat bot that seems to be receiving messages from another bot. we'd like to ignore these messages, as responding to them leads to an infinite loop of ping pong between the two bots.
we were hoping to rely on activity.from.role as documented here, but it seems like that field is never set.
activity.from.id looks something like 28:app:00000000-dfae-4fe1-a068-80fe8fc61f2b_62b732f7-fc71-40bc-b27d-35efcb000000, and we are thinking that the only way to identify the account as a bot is by detecting the :app: in these IDs. this is sub-optimal, as this ID format is not part of the official API and could change at any time.
that said, how should we detect if an activity event is coming from a bot?
If you've to deal with potential bots from outside your organisation, a simple way could be to keep a dictionary of few last text exchanges indexed by userId or UserName in the Activity object. Then, at each POST received by your bot, check if the received text match fully one of the precedent message entries in this dictionary. If it is the case, then mark the related userId/UserName as a candidate for the bot role but continue to check further text exchanges in case a non bot user just said hi twice.
If the few following further exchanges doesn't meet anymore the full match requirement, unmark the userId/UserName as a potential bot. If there is marked UserId/UserName as candidate for bot role, apply the bot role to them if there's no more further exchanges past the full match entry or after a delay of your choice. For the latter, it might be useful to provoke a last text exchange after the delay to decide.
For the Watson/Eliza kind of bots, i recommended to check the speed of the exchanges, as far as i know, no human being can exchange more than twenty messages per second.

Using MS Teams, Power Automate and Adaptive Cards: how to use inputs from user using the Flow Bot to use in another Adaptive Card

I'm trying out Powerapps and would like to try out this low code approach.
The idea is as follows:
Display an Adaptive Card (going to use the sample one) to the user using Microsoft Flow/Power Automate application within Teams.
The user would then input some information on the card and submit it
Use that input that was submitted to populate another Adaptive Card.
To illustrate the above, in Power Automate:
Here is how the output is displayed when used in the Schema Explorer for Action.Submit:
In Microsoft Teams, the Flow bot will display the ticket to the user to be filled in:
How can I get the values from the inputs and reuse them in Power Automate. Does anyone know how to get those values and reuse in the next step (see first image) ?
Thank you in advance for your assistance. Would appreciate any help.
Basically, the problem is that the "submit" action of the Adaptive Card returns the response to the original source, in this case the "Flow Bot". However, Flow Bot is a general bot, and doesn't have a way to route the response back to your individual Flow, and specifically to the instance of the Flow. Thankfully, this is changing - see here for information. It's not clear from the post whether it will handle the "Bot-to-user" scenario in version 1 though, which I see you use in your solution, and also, as stated in the blog, it's only expected in Feb. So, it would seem there are two options:
Wait till Feb for the new feature
Create your own Bot to send the cards from, and handle the responses - there are a few small tricky parts here as you need to send the initial message on a schedule, so you'd be using something called "pro-active messaging", but it's not too complex and something there's good guidance on here in Stack Overflow (I've myself answered a few questions recently on it so can help more if you go this route)
Not an ideal answer I'm sure you were looking for, but hopefully it helped
#Carike, There is one more way you can implement this scenario is by handling all your action of adaptive card submission event in different flow. You can set the trigger as "When HTTP request received" for the second flow. When you set this trigger, you receive one url - which you can set as the submit URL of the first flow's adaptive card.

WaterfallStep design vs. SOLID principales in Bot Framework v4

After moving over from Bot Framework v3 and studying the docs/samples, I'm still not understanding why the WaterfallStep dialog handling in v4 was implemented in such a way.
Why was it chosen to process the result of the previous step in the next step within a waterfall?
Given a waterfall with 3 Steps PromptName, PromptAge and PromptLocation, I see the following:
Method naming: Given the 2nd and 3rd prompt, method naming gets unclear. Naturally we would do AskForAge() or AskForLocation() but this is misleading due to the next point
SOLID Principals: Isn't "single responsibility principal" violated as we do two things in each step? Storing the previous response while asking for the next one in the same method, which ultimately leads in method names like AskForLocationAndStoreAge()
Code duplication: Due to the fact that each step assumes concrete input from its previous step, it can't be reused easily nor can order be changed. Even the simplest samples are hard to read.
I'm looking for some clarification on why the design was chosen this way or what I have missed in the concept.
This question seems largely opinion-based and therefore I don't know that it is appropriate for Stack Overflow. It turns out there is actually a good place to ask these kinds of questions, and it's the BotBuilder GitHub repo. I will attempt to answer it all the same.
Why was it chosen to process the result of the previous step in the next step within a waterfall?
This has to do with how bot conversations work. In its most basic form, without any dialogs or state or anything, a bot works by answering questions or otherwise responding to messages from the user. That is to say, a bot program's entire lifespan is to receive one message, process it, and provide a response while the message it received is still "active" in some sense. Then every following message the bot receives from the user is processed in the same way as though the first message was never received, like the message is being processed by an entirely new instance of the program with no memory of previous messages.
To make bot conversations feel more continuous, bot state and dialogs are needed. With dialogs and specifically prompt dialogs, the bot is now able to ask the user a question rather than just answer questions the user asked. In order to do this, the bot needs to store information about the conversation somewhere so that when the next message is received from the user the new "instance" of the bot program will know that the message from the user should be interpreted as a response to the question that the previous instance of the program asked. It's like leaving a note for someone working the next shift to let them know about something that happened during the previous shift that they need to follow up on.
Knowing all this, it seems only natural to process the result of the previous step in the next step within a waterfall because of the nature of conversations and dialogs. In a waterfall dialog containing prompts, the bot will receive messages pertaining to the last message the bot sent. So it needs to process the result of the previous step in the next step. It also needs to respond to the message, and in a waterfall that often means asking another question.
Isn't "single responsibility principal" violated as we do two things in each step? Storing the previous response while asking for the next one in the same method, which ultimately leads in method names like AskForLocationAndStoreAge()
As I understand it, the single responsibility principle refers to classes and not methods. If it does refer to methods, then that principle may well be violated or bent in some way in this case. However, it doesn't have to be. You are free to make multiple methods to handle each step, or even to make multiple steps to handle each message. If you wanted, your waterfall could contain a step that processes the result of the previous prompt and then continues on into the next step which makes a new prompt.
Due to the fact that each step assumes concrete input from its previous step, it can't be reused easily nor can order be changed. Even the simplest samples are hard to read.
You ultimately have control over how the input is validated/interpreted so it can be as concrete as you want. The reusability of a dialog or waterfall step has everything to do with how similar the different things you want to do are, the same as in any area of programming. If the samples are hard to read, I recommend raising issues with those samples. Of course, you can still raise an issue with the design of the SDK itself in the appropriate repo, but please do consider including suggestions for the way you think it should be instead.

Comment filter design for closed topics

In my app, multiple people can chat on a topic. However once the topic has been closed by its owner, chat should also be disabled on that topic.
My Tables -
ChatComment - a new comment is stored here as a record - it contains pointer to Topic
Topic - details related to topic for eg. body, owner, status - open/closed
I'm using cloud functions to create a new comment made by a person on its owner. So everytime I call the cloud function to write new comment, it first queries 'Topic' class to check if topic is still open or not, if its open itll go forward to create new comment in comment class, or else it will throw error.
My problem is that in realtime so many people chat on the topic so frequently that the first query(that checks if topic is still open) occurs for each comment and adds a delay. It really kills user experience.
Can we write a filter to meet above conditions? Please advice me how to deal with this in any other way if possible?
A common pattern is to fake it, the idea works like this:
For the user making the comment, as soon as they enter a comment show it in the topic as if it was added normally. Then start the async call to your cloud function and update the status based on the result.
You might choose to do nothing with the confirmation, or do something like iOS Messages app that shows a "Delivered" tag.
If the cloud function comes back with an error because the topic was closed, update the message to highlight that it was rejected (strikethrough is appropriate here) and disable the ability to add more comments.
This gives the illusion of speed in a delayed system.

EventSourcing fix business logic bugs

I'm making some study of eventsourcing before applying it (or not).
Quick question : When using EventSourcing pattern we can imagine this scenario to handle an event :
command sent
command handler receive the previous command, validate it then
command handler persist this event and publish it
business model apply (business logic algorithm v1 for example) this event mutating its internal state
We can replay all the events and reconstruct the business object state.
How to handle business logic bugs (business logic algorithm v1 contains a nasty bugs).
I read we can fix the bug and replay the events and then we got the business model in a valid state once again.
But what happens if when fixing the business rule when applying event#1 would have caused the 'futurs' commands to fails ? In other words, the event#2, event#3, event#n was dependend of the state of the domain model after applying event#0. How can we fix the cascading events failure ?
I don't have a specific usecase : but we can imagine an account where balance is currently positive. Applying Event#0 increment the balance but this was a bug, the developer wanted to reduce the balance. Event#1 is a purchase that was valid because of the positive balance at this time.
The developer fixes the bug and replay the events. Event#0 decrease the balance which becomes negative. Event#1 is replayed : what happens ?
Do we need to handle this case with 'compensation' ? how ?
thanks in advance for your comments, external ressources that can be of any help (articles, blogs).
bye
Minor correction
When using EventSourcing pattern we can imagine this scenario to handle an event
command sent
command handler receive the previous command, validate it then
business model verifies that the command can be satisfied without violating the business invariant, and calculates the ensuing events
command handler persist this events and publish them
The command handler (specifically, the anti-corruption layer) is responsible for making sure that the command is well formed. The business model decides if the command is permitted by the business.
The good news: the events are just state changes; all of the rule validation is already done. When you fix the bug in the domain object so that it produces the correct events in response to the command, you aren't changing the way the event is applied.
And you certainly aren't changing the history -- if the ATM gave away $20 that it wasn't supposed to, you can't get the money back by editing the record.
What that means is that deploying the bug fix keeps the problem from getting worse; but it doesn't do anything for the event histories that are incorrect.
Compensating events are the right answer here. Ever have a grocery clerk double scan an item, and have to back one of them out? If you look closely, you'll see all three items
+1 candy bar
+1 candy bar
-1 candy bar
That's the idiom of the compensating event being appended to end of the stream.
So if the error showed first appeared in event #0, and then [event #1 .. event #99] have been played on top of that, the remedy for the error is to publish a compensating event #100.
Notice that this is exactly what book keepers would do. You put the wrong sign on the entry on line #1, add a bunch more entries, realize your mistake, and add a new entry that compensates for the earlier mistake.
More good news: in mature business processes, there are already mitigation procedures in place to handle various contingencies. So you can grab a meeting with your domain experts, and doodle on the whiteboard explaining the problem, and your experts should be able to show you the right way to compensate for it. Everything after that is feature management (does the mitigation need to be automated? Does the system need to do the mitigation automatically, or can it let human experts tell it what mitigation to apply, etc. etc.)

Resources