I am using python sdk of botframework for my bot design. I am using waterfall style of dialogs for my conversation design.
My bot starts with a dialog by asking user: "I can show documents for topic A, B, C. Of what topic you would like to see documents?"
To verify if the user has submitted right topic, I use custom Validator and using luis I verify if the user has entered correct topic.
In waterfall step of dialog, I use the topic entered by user to show him the respective topics. But here also I have to hit luis service again to extract the topic from the user message and then using that entity filter from the list of topics.
My question is: Is it possible to pass on the values from the promptValidatorContext to current step context or the next dialog in the waterfall dialog set.
As you can see with following sample code, I am hitting the luis app twice with the same user message, if it's possible to share values between promptValidatorContext and dialogContext, this would me help me avoid hitting luis service twice and could do the same job with one time hitting.
Sample code:
class MainDialog(ComponentDialog):
def __init__(self, dialog_id, luis_app):
self.dialog_id = dialog_id
self.luis_app = luis_app
self.add_dialog(TextPrompt('topic', self.TopicValidator))
self.add_dialog(WaterFallDialog('wf_dialog', [self.Welcome, self.Topic, self.FinalStep])
async def Welcome(self, step_context):
return await step_context.prompt(
'topic',
options = PromptOptions(
prompt = MessageFactory.text('Welcome to the bot, I can show you documents of topic Math, English, Science'),
retry_prompt = MessageFactory.text("I am sorry I didn't understand please try again with different wording")
)
)
async def TopicValidator(self, prompt_context: PromptValidatorContext):
for_luis = prompt_context.recognized.value
#hit the luis app to get the topic name
topic_name = self.luis_app(for_luis)
if topic_name in ['Math', 'Science', 'English']:
return True
else:
return False
async def Topic(self, step_context):
topic_name = self.luis_app(step_context.context.activity.text) #using the same user message as used in Validator function
#filter documents based on topics with custom function filter_doc
docs = filter_doc(topic_name)
return await step_context.prompt('docs', options = PromptOptions(prompt = docs))
async def FinalStep(self, step_context):
#code for final step
luis_app
is a function that calls your LUIS endpoint and is not an actualLuisApplication
object. Is that correct? If so, I can see that you are needlessly calling the endpoint twice and you'd rather just call it once. I can think of several ways to answer your question as you've asked it, but I suspect there's a better question that you didn't ask. Is your text prompt just trying to get the user to pick one of three possible options? If so, you should be using a choice prompt instead. You asked how to call LUIS only once, but maybe you can call it zero times. – Kyle Delaney