예제 #1
0
    async def interrupt(self, inner_dc: DialogContext) -> DialogTurnResult:
        if inner_dc.context.activity.type == ActivityTypes.message:
            text = inner_dc.context.activity.text.lower()

            intent, score, luis_result = await LuisHelper.execute_luis_query(
                self._luis_recognizer, inner_dc.context)

            if intent == 'help_okr':

                help_message_text = self._action.get_random_utterance(
                    'show_help')
                help_message = MessageFactory.text(help_message_text,
                                                   help_message_text,
                                                   InputHints.expecting_input)
                await inner_dc.context.send_activity(help_message)
                return DialogTurnResult(DialogTurnStatus.Waiting)

            elif intent == 'withdraw_okr':

                cancel_message_text = self._action.get_random_utterance(
                    'cancel')
                cancel_message = MessageFactory.text(cancel_message_text,
                                                     cancel_message_text,
                                                     InputHints.ignoring_input)
                await inner_dc.context.send_activity(cancel_message)
                return await inner_dc.cancel_all_dialogs()

        return None
    async def continue_dialog(self, dialog_context: DialogContext):
        activity = dialog_context.context.activity
        if (
            activity.type == ActivityTypes.event
            and activity.name == ActivityEventNames.continue_conversation
        ):
            # We continued the conversation, forget the proactive reference.
            self.continuation_parameters_store[activity.id] = None

            # The continue conversation activity comes from the ProactiveController when the notification is received
            await dialog_context.context.send_activity(
                "We received a proactive message, ending the dialog"
            )

            # End the dialog so the host gets an EoC
            await dialog_context.context.send_activity(
                Activity(
                    type=ActivityTypes.end_of_conversation,
                    code=EndOfConversationCodes.completed_successfully,
                )
            )
            return DialogTurnResult(DialogTurnStatus.Complete)

        # Keep waiting for a call to the ProactiveController.
        await dialog_context.context.send_activity(
            f"We are waiting for a proactive message. "
            f"{self.notify_message(self.configuration, activity.from_property.id)}"
        )

        return Dialog.end_of_turn
예제 #3
0
    async def handle_action_step(self, step_context: WaterfallStepContext):
        action = str(step_context.result.value).lower()

        if action == "login":
            return await step_context.begin_dialog(
                SsoSkillSignInDialog.__name__)

        if action == "logout":
            await step_context.context.adapter.sign_out_user(
                step_context.context, self.connection_name)
            await step_context.context.send_activity(
                "You have been signed out.")
            return await step_context.next(None)

        if action == "show token":
            token = await step_context.context.adapter.get_user_token(
                step_context.context, self.connection_name)

            if token is None:
                await step_context.context.send_activity(
                    "User has no cached token.")
            else:
                await step_context.context.send_activity(
                    f"Here is your current SSO token: { token.token }")

            return await step_context.next(None)

        if action == "end":
            return DialogTurnResult(DialogTurnStatus.Complete)

        # This should never be hit since the previous prompt validates the choice.
        raise Exception(f"Unrecognized action: { action }")
예제 #4
0
    async def final_step(self, step_context: WaterfallStepContext):
        try_another = step_context.result

        if try_another:
            return await step_context.replace_dialog(self.initial_dialog_id)

        return DialogTurnResult(DialogTurnStatus.Complete)
    async def final_step(self, step_context: WaterfallStepContext):
        try_another = step_context.result
        if try_another:
            return await step_context.replace_dialog(self.initial_dialog_id)

        self._update_tracker.pop(step_context.context.activity.conversation.id)

        return DialogTurnResult(DialogTurnStatus.Complete)
    async def _on_message_activity(
        self, step_context: WaterfallStepContext
    ) -> DialogTurnResult:
        """
        This method just gets a message activity and runs it through LUIS.
        """

        activity = step_context.context.activity

        if not self._luis_recognizer.is_configured:
            await step_context.context.send_activity(
                MessageFactory.text(
                    "NOTE: LUIS is not configured. To enable all capabilities, add 'LuisAppId', 'LuisAPIKey' and"
                    " 'LuisAPIHostName' to the config.py file.",
                    input_hint=InputHints.ignoring_input,
                )
            )
        else:
            # Call LUIS with the utterance.
            luis_result = await self._luis_recognizer.recognize(step_context.context)

            message = f'LUIS results for "{activity.Text}":\n'
            intent, intent_score = None, None
            if luis_result.intents:
                max_value_key = max(
                    luis_result.intents, key=lambda key: luis_result.intents[key]
                )
                intent, intent_score = max_value_key, luis_result.intents[max_value_key]

            message += f'Intent: "{intent}" Score: {intent_score}\n'

            await step_context.context.send_activity(
                MessageFactory.text(message, input_hint=InputHints.ignoring_input,)
            )

            # Start a dialog if we recognize the intent.
            top_intent = luis_result.get_top_scoring_intent().intent

            if top_intent == "BookFlight":
                return await self._begin_book_flight(step_context)

            if top_intent == "GetWeather":
                return await self._begin_get_weather(step_context)

            # Catch all for unhandled intents.
            didnt_understand_message_text = f"Sorry, I didn't get that. Please try asking in a different way (intent was {top_intent})"
            await step_context.context.send_activity(
                MessageFactory.text(
                    didnt_understand_message_text,
                    didnt_understand_message_text,
                    input_hint=InputHints.ignoring_input,
                )
            )

        return DialogTurnResult(DialogTurnStatus.Complete)
예제 #7
0
    async def final_step(self, step_context: WaterfallStepContext):
        try_another = step_context.result

        if try_another:
            return await step_context.replace_dialog(self.initial_dialog_id)

        await step_context.context.send_activity(
            Activity(
                type=ActivityTypes.end_of_conversation,
                code=EndOfConversationCodes.completed_successfully,
            ))
        return DialogTurnResult(DialogTurnStatus.Complete)
    async def on_event_activity(self, step_context: WaterfallStepContext):
        activity = step_context.context.activity
        await step_context.context.send_activity(
            Activity(
                type=ActivityTypes.trace,
                timestamp=datetime.utcnow(),
                name="ActivityRouterDialog.on_event_activity()",
                label=
                f"Name: {activity.name}. Value: {json.dumps(activity.value)}",
            ))

        if activity.name == "Cards":
            return await step_context.begin_dialog(CardDialog.__name__)

        if activity.name == "Proactive":
            return await step_context.begin_dialog(
                WaitForProactiveDialog.__name__)

        if activity.name == "MessageWithAttachment":
            return await step_context.begin_dialog(
                MessageWithAttachmentDialog.__name__)

        if activity.name == "Auth":
            return await step_context.begin_dialog(AuthDialog.__name__)

        if activity.name == "Sso":
            return await step_context.begin_dialog(SsoSkillDialog.__name__)

        if activity.name == "FileUpload":
            return await step_context.begin_dialog(FileUploadDialog.__name__)

        if activity.name == "Echo":
            # Start the EchoSkillBot
            message_activity = MessageFactory.text("I'm the echo skill bot")
            message_activity.delivery_mode = activity.delivery_mode
            dialog = await self.find_dialog(ECHO_SKILL)
            return await step_context.begin_dialog(
                dialog.id, BeginSkillDialogOptions(activity=message_activity))

        if activity.name == "Delete":
            return await step_context.begin_dialog(DeleteDialog.__name__)

        if activity.name == "Update":
            return await step_context.begin_dialog(UpdateDialog.__name__)

        # We didn't get an event name we can handle.
        await step_context.context.send_activity(
            activity_or_text=
            f'Unrecognized EventName: "{step_context.context.activity.name}".',
            input_hint=InputHints.ignoring_input,
        )
        return DialogTurnResult(DialogTurnStatus.Complete)
    async def interrupt(self, inner_dc: DialogContext) -> DialogTurnResult:
        if inner_dc.context.activity.type == ActivityTypes.message:
            text = inner_dc.context.activity.text.lower()

            if text == 'help' or text == '?':
                await inner_dc.context.send_activity("Show Help...")
                return DialogTurnResult(DialogTurnStatus.Waiting)

            if text == 'cancel' or text == 'quit':
                await inner_dc.context.send_activity("Cancelling")
                return await inner_dc.cancel_all_dialogs()

        return None
예제 #10
0
    async def _insert_info(
            self, step_context: WaterfallStepContext) -> DialogTurnResult:
        # uses adaptive cards to insert data
        step_context.values.update(step_context.options)

        message = Activity(
            text="Compila la seguente scheda",
            type=ActivityTypes.message,
            attachments=[INSERT_PERSON_CARD],
        )

        await step_context.context.send_activity(message)
        return DialogTurnResult(status=DialogTurnStatus.Waiting, result={})
    async def interrupt(self, inner_dc: DialogContext) -> DialogTurnResult:
        """Detect interruptions."""
        if inner_dc.context.activity.type == ActivityTypes.message:
            text = inner_dc.context.activity.text.lower()

            if text in ("help", "?"):
                await inner_dc.context.send_activity("Show Help...")
                return DialogTurnResult(DialogTurnStatus.Waiting)

            if text in ("cancel", "quit"):
                await inner_dc.context.send_activity("Cancelling")
                return await inner_dc.cancel_all_dialogs()

        return None
예제 #12
0
    async def first_step(
            self, step_context: WaterfallStepContext) -> DialogTurnResult:
        """Prompt for destination."""
        card_details = step_context.options

        food_card = self.create_adaptive_card_attachment()
        response = self.create_response(step_context.context.activity,
                                        food_card)
        await step_context.context.send_activity(response)
        await step_context.context.send_activity('Card')

        if step_context.context.activity.value is None:
            return DialogTurnResult(DialogTurnStatus.Waiting)

        return await step_context.next(card_details)
    async def handle_update_dialog_step(self,
                                        step_context: WaterfallStepContext):
        channel = step_context.context.activity.channel_id
        if channel in self._update_supported:
            if step_context.context.activity.conversation.id in self._update_tracker:
                conversation_id = step_context.context.activity.conversation.id
                tracked_tuple = self._update_tracker[conversation_id]
                activity = MessageFactory.text(
                    f"This message has been updated {tracked_tuple.item2} time(s)."
                )

                tracked_tuple.item2 += 1
                activity.id = tracked_tuple.item1
                self._update_tracker[conversation_id] = tracked_tuple

                await step_context.context.update_activity(activity)

            else:
                response = await step_context.context.send_activity(
                    MessageFactory.text("Here is the original activity."))
                self._update_tracker[
                    step_context.context.activity.conversation.id] = (
                        response.id,
                        1,
                    )

        else:
            await step_context.context.send_activity(
                MessageFactory.text(
                    f"Delete is not supported in the {channel} channel."))

            await step_context.context.send_activity(
                Activity(
                    type=ActivityTypes.end_of_conversation,
                    code=EndOfConversationCodes.completed_successfully,
                ))
            return DialogTurnResult(DialogTurnStatus.Complete)

        # Ask if we want to update the activity again.
        message_text = "Do you want to update the activity again?"
        reprompt_message_text = "Please select a valid answer"
        options = PromptOptions(
            prompt=MessageFactory.text(message_text, message_text),
            retry_prompt=MessageFactory.text(reprompt_message_text,
                                             reprompt_message_text),
        )

        return await step_context.prompt(ConfirmPrompt.__name__, options)
예제 #14
0
    async def handle_delete_dialog_step(self,
                                        step_context: WaterfallStepContext):
        channel = step_context.context.activity.channel_id

        if channel in self._delete_supported:
            response = await step_context.context.send_activity(
                MessageFactory.text("I will delete this message in 5 seconds"))
            time.sleep(5)
            await step_context.context.delete_activity(response.id)

        else:
            await step_context.context.send_activity(
                MessageFactory.text(
                    f"Delete is not supported in the {channel} channel."))

        return DialogTurnResult(DialogTurnStatus.Complete)
    async def _begin_get_weather(
        self, step_context: WaterfallStepContext
    ) -> DialogTurnResult:
        activity = step_context.context.activity
        location = Location()
        if activity.value:
            location.from_json(activity.value)

        # We haven't implemented the GetWeatherDialog so we just display a TODO message.
        get_weather_message = f"TODO: get weather for here (lat: {location.latitude}, long: {location.longitude}"
        await step_context.context.send_activity(
            MessageFactory.text(
                get_weather_message, get_weather_message, InputHints.ignoring_input,
            )
        )

        return DialogTurnResult(DialogTurnStatus.Complete)
    async def interrupt(self, inner_dc: DialogContext) -> DialogTurnResult:
        """Detect interruptions."""
        if inner_dc.context.activity.type == ActivityTypes.message:
            text = inner_dc.context.activity.text.lower()

            if text == "help" or text == "?":
                await inner_dc.context.send_activity("Show Help...")
                return DialogTurnResult(DialogTurnStatus.Waiting)

            if text == "cancel" or text == "quit":
                await inner_dc.context.send_activity("Cancelling")
                return await inner_dc.cancel_all_dialogs()

            if text == "menu":
                await inner_dc.context.send_activity(MessageFactory.text('Возврат меню'))
                return await inner_dc.cancel_all_dialogs()

        return None
예제 #17
0
    async def _on_event_activity(
            self, step_context: WaterfallStepContext) -> DialogTurnResult:
        activity = step_context.context.activity

        # Resolve what to execute based on the event name.
        if activity.name == "BookFlight":
            return await self._begin_book_flight(step_context)

        if activity.name == "GetWeather":
            return await self._begin_get_weather(step_context)

        # We didn't get an activity name we can handle.
        await step_context.context.send_activity(
            MessageFactory.text(
                f'Unrecognized ActivityName: "{activity.name}".',
                input_hint=InputHints.ignoring_input,
            ))
        return DialogTurnResult(DialogTurnStatus.Complete)
예제 #18
0
    async def __check_for_multiturn_prompt(self, step_context: WaterfallStepContext):
        dialog_options: QnAMakerDialogOptions = ObjectPath.get_path_value(
            step_context.active_dialog.state, QnAMakerDialog.KEY_OPTIONS
        )

        response = step_context.result
        if response and isinstance(response, List):
            answer = response[0]
            if answer.context and answer.context.prompts:
                previous_context_data = ObjectPath.get_path_value(
                    step_context.active_dialog.state,
                    QnAMakerDialog.KEY_QNA_CONTEXT_DATA,
                    {},
                )
                for prompt in answer.context.prompts:
                    previous_context_data[prompt.display_text] = prompt.qna_id

                ObjectPath.set_path_value(
                    step_context.active_dialog.state,
                    QnAMakerDialog.KEY_QNA_CONTEXT_DATA,
                    previous_context_data,
                )
                ObjectPath.set_path_value(
                    step_context.active_dialog.state,
                    QnAMakerDialog.KEY_PREVIOUS_QNA_ID,
                    answer.id,
                )
                ObjectPath.set_path_value(
                    step_context.active_dialog.state,
                    QnAMakerDialog.KEY_OPTIONS,
                    dialog_options,
                )

                # Get multi-turn prompts card activity.
                message = QnACardBuilder.get_qna_prompts_card(
                    answer, dialog_options.response_options.card_no_match_text
                )
                await step_context.context.send_activity(message)

                return DialogTurnResult(DialogTurnStatus.Waiting)

        return await step_context.next(step_context.result)
    async def process_activity(self, step_context: WaterfallStepContext):
        # A skill can send trace activities, if needed.
        await step_context.context.send_activity(
            Activity(
                type=ActivityTypes.trace,
                timestamp=datetime.utcnow(),
                name="ActivityRouterDialog.process_activity()",
                label=f"Got ActivityType: {step_context.context.activity.type}",
            ))

        if step_context.context.activity.type == ActivityTypes.event:
            return await self.on_event_activity(step_context)

        # We didn't get an activity type we can handle.
        await step_context.context.send_activity(
            activity_or_text=
            f'Unrecognized ActivityType: "{step_context.context.activity.type}".',
            input_hint=InputHints.ignoring_input,
        )
        return DialogTurnResult(DialogTurnStatus.Complete)
    async def interrupt(self, inner_dc: DialogContext) -> DialogTurnResult:
        if inner_dc.context.activity.type == ActivityTypes.message:
            text = inner_dc.context.activity.text.lower()
            help_message = Activity(
                type=ActivityTypes.message,
                attachments=[CardFactory.adaptive_card(Cards.help_card)],
            )

            if text in ("help", "?"):
                await inner_dc.context.send_activity(help_message)
                return DialogTurnResult(DialogTurnStatus.Waiting)

            cancel_message_text = "Cancelled."
            cancel_message = MessageFactory.text(
                cancel_message_text, cancel_message_text, InputHints.ignoring_input
            )

            if text in ("cancel", "quit", "exit"):
                await inner_dc.context.send_activity(cancel_message)
                return await inner_dc.cancel_all_dialogs()

        return None
예제 #21
0
    async def process_activity(
            self, step_context: WaterfallStepContext) -> DialogTurnResult:
        current_activity_type = step_context.context.activity.type

        # A skill can send trace activities, if needed.
        await step_context.context.send_trace_activity(
            f"{ActivityRouterDialog.__name__}.process_activity()",
            label=f"Got ActivityType: {current_activity_type}",
        )

        if current_activity_type == ActivityTypes.event:
            return await self._on_event_activity(step_context)
        if current_activity_type == ActivityTypes.message:
            return await self._on_message_activity(step_context)
        else:
            # We didn't get an activity type we can handle.
            await step_context.context.send_activity(
                MessageFactory.text(
                    f'Unrecognized ActivityType: "{current_activity_type}".',
                    input_hint=InputHints.ignoring_input,
                ))
            return DialogTurnResult(DialogTurnStatus.Complete)
예제 #22
0
    async def interrupt(self, inner_dc: DialogContext) -> DialogTurnResult:
        LOGGER.debug(msg=f"{CancelAndHelpDialog.__name__}: interrupt")

        if inner_dc.context.activity.type == ActivityTypes.message:
            text = inner_dc.context.activity.text.lower()
            message = Activity(
                type=ActivityTypes.message,
                attachments=[CardFactory.adaptive_card(HelpCard)])

            if text in (Prompts.HELP.value, Prompts.QUESTION_MARK.value):
                await inner_dc.context.send_activity(message)
                return DialogTurnResult(DialogTurnStatus.Waiting)

            if text in (Prompts.CANCEL.value, Prompts.END.value,
                        Prompts.QUIT.value):
                cancel_message = MessageFactory.text(messages.CANCELLED,
                                                     messages.CANCELLED,
                                                     InputHints.ignoring_input)
                await inner_dc.context.send_activity(cancel_message)
                await inner_dc.cancel_all_dialogs()
                return await inner_dc.replace_dialog(self.initial_dialog_id)
        return None
예제 #23
0
    async def interrupt(self, inner_dc: DialogContext) -> DialogTurnResult:
        if inner_dc.context.activity.type == ActivityTypes.message:
            text = inner_dc.context.activity.text.lower()

            help_message_text = "Show Help..."
            help_message = MessageFactory.text(help_message_text,
                                               help_message_text,
                                               InputHints.expecting_input)

            if text in ("help", "?"):
                await inner_dc.context.send_activity(help_message)
                return DialogTurnResult(DialogTurnStatus.Waiting)

            cancel_message_text = "Cancelling"
            cancel_message = MessageFactory.text(cancel_message_text,
                                                 cancel_message_text,
                                                 InputHints.ignoring_input)

            if text in ("cancel", "quit"):
                await inner_dc.context.send_activity(cancel_message)
                return await inner_dc.cancel_all_dialogs()

        return None
예제 #24
0
    async def interrupt(self, inner_dc: DialogContext) -> DialogTurnResult:
        if inner_dc.context.activity.type == ActivityTypes.message:
            text = inner_dc.context.activity.text.lower()

            help_message_text = "Please tell me the Azure AI service/area. We will find their PM/Dev contact for you."
            help_message = MessageFactory.text(
                help_message_text, help_message_text, InputHints.expecting_input
            )

            if text in ("help", "?"):
                await inner_dc.context.send_activity(help_message)
                return DialogTurnResult(DialogTurnStatus.Waiting)

            cancel_message_text = "Cancelling"
            cancel_message = MessageFactory.text(
                cancel_message_text, cancel_message_text, InputHints.ignoring_input
            )

            if text in ("cancel", "quit", "exit", 'bye'):
                await inner_dc.context.send_activity(cancel_message)
                return await inner_dc.cancel_all_dialogs()

        return None
예제 #25
0
    async def interrupt(self, inner_dc: DialogContext) -> DialogTurnResult:
        if inner_dc.context.activity.type == ActivityTypes.message:
            text = inner_dc.context.activity.text.lower()

            help_message_text = "Sono un bot dotato di intelligenza artificiale che ti permette di:\n\n- Ricercare libri e mostrarti i prezzi migliori sul mercato.\n- Creare una wishlist dove poter inserire tutti i libri che ti interessano.\n- Mantenere sott'occhio i libri della tua wishlist e avvisarti se cambiano di prezzo, o ritornano disponibili.\n- Posso offrirti suggerimenti su nuovi libri da leggere in base alle tue preferenze.\n- Posso guidarti all'acquisto di nuovi libri, confrontando le varie recensioni per un particolare libro che ti interessa.\n\nPuoi utilizzarmi come preferisci, puoi impartirmi comandi, oppure utilizzare i bottoni del menu. "
            help_message = MessageFactory.text(help_message_text,
                                               help_message_text,
                                               InputHints.expecting_input)

            if text.lower() in ("help", "?"):
                await inner_dc.context.send_activity(help_message)
                return DialogTurnResult(DialogTurnStatus.Waiting)

            cancel_message_text = "Cancelling"
            cancel_message = MessageFactory.text(cancel_message_text,
                                                 cancel_message_text,
                                                 InputHints.ignoring_input)

            if text.lower() in ("cancel", "quit"):
                await inner_dc.context.send_activity(cancel_message)
                return await inner_dc.cancel_all_dialogs()

        return None
    async def display_card_step(self, step_context: WaterfallStepContext):
        if step_context.context.activity.value is not None:
            await self.handle_special_activity(step_context)
        else:
            # Check to see if the activity is an adaptive card or a bot action response
            card_type = CardOptions(step_context.result.value)

            if ChannelSupportedCards.is_card_supported(
                    step_context.context.activity.channel_id, card_type):
                if card_type == CardOptions.ADAPTIVE_CARD_BOT_ACTION:
                    await step_context.context.send_activity(
                        MessageFactory.attachment(
                            CardSampleHelper.create_adaptive_card_bot_action())
                    )

                elif card_type == CardOptions.ADAPTIVE_CARD_TEAMS_TASK_MODULE:
                    await step_context.context.send_activity(
                        MessageFactory.attachment(
                            CardSampleHelper.create_adaptive_card_task_module(
                            )))

                elif card_type == CardOptions.ADAPTIVE_CARD_SUBMIT_ACTION:
                    await step_context.context.send_activity(
                        MessageFactory.attachment(
                            CardSampleHelper.create_adaptive_card_submit()))

                elif card_type == CardOptions.HERO:
                    await step_context.context.send_activity(
                        MessageFactory.attachment(
                            CardSampleHelper.create_hero_card()))

                elif card_type == CardOptions.THUMBNAIL:
                    await step_context.context.send_activity(
                        MessageFactory.attachment(
                            CardSampleHelper.create_thumbnail_card()))

                elif card_type == CardOptions.RECEIPT:
                    await step_context.context.send_activity(
                        MessageFactory.attachment(
                            CardSampleHelper.create_receipt_card()))

                elif card_type == CardOptions.SIGN_IN:
                    await step_context.context.send_activity(
                        MessageFactory.attachment(
                            CardSampleHelper.create_signin_card()))

                elif card_type == CardOptions.CAROUSEL:
                    #  NOTE if cards are NOT the same height in a carousel,
                    #  Teams will instead display as AttachmentLayoutTypes.List
                    await step_context.context.send_activity(
                        MessageFactory.carousel([
                            CardSampleHelper.create_hero_card(),
                            CardSampleHelper.create_hero_card(),
                            CardSampleHelper.create_hero_card(),
                        ]))

                elif card_type == CardOptions.LIST:
                    await step_context.context.send_activity(
                        MessageFactory.list([
                            CardSampleHelper.create_hero_card(),
                            CardSampleHelper.create_hero_card(),
                            CardSampleHelper.create_hero_card(),
                        ]))

                elif card_type == CardOptions.O365:
                    await step_context.context.send_activity(
                        MessageFactory.attachment(
                            CardSampleHelper.create_o365_connector_card()))

                elif card_type == CardOptions.TEAMS_FILE_CONSENT:
                    await step_context.context.send_activity(
                        MessageFactory.attachment(
                            CardSampleHelper.create_teams_file_consent_card(
                                TEAMS_LOGO_FILE_NAME)))

                elif card_type == CardOptions.ANIMATION:
                    await step_context.context.send_activity(
                        MessageFactory.attachment(
                            CardSampleHelper.create_animation_card(
                                MIND_BLOWN_GIF)))

                elif card_type == CardOptions.AUDIO:
                    await step_context.context.send_activity(
                        MessageFactory.attachment(
                            CardSampleHelper.create_audio_card(
                                f"{self.configuration.SERVER_URL}/{MUSIC_API}")
                        ))

                elif card_type == CardOptions.VIDEO:
                    await step_context.context.send_activity(
                        MessageFactory.attachment(
                            CardSampleHelper.create_video_card(
                                CORGI_ON_CAROUSEL_VIDEO)))

                elif card_type == CardOptions.ADAPTIVE_UPDATE:
                    await step_context.context.send_activity(
                        MessageFactory.attachment(
                            CardSampleHelper.create_adaptive_update_card()))

                elif card_type == CardOptions.END:
                    # End the dialog so the host gets an EoC
                    await step_context.context.send_activity(
                        Activity(
                            type=ActivityTypes.end_of_conversation,
                            code=EndOfConversationCodes.completed_successfully,
                        ))
                    return DialogTurnResult(DialogTurnStatus.Complete)

            else:
                await step_context.context.send_activity(
                    f"{card_type.value} cards are not supported in the "
                    f"{step_context.context.activity.channel_id} channel.")

        return await step_context.replace_dialog(self.initial_dialog_id,
                                                 "What card would you want?")
예제 #27
0
    async def __call_generate_answer(self, step_context: WaterfallStepContext):
        dialog_options: QnAMakerDialogOptions = ObjectPath.get_path_value(
            step_context.active_dialog.state, QnAMakerDialog.KEY_OPTIONS
        )

        # Resetting context and QnAId
        dialog_options.options.qna_id = 0
        dialog_options.options.context = QnARequestContext()

        # Storing the context info
        step_context.values[
            QnAMakerDialog.PROPERTY_CURRENT_QUERY
        ] = step_context.context.activity.text

        # -Check if previous context is present, if yes then put it with the query
        # -Check for id if query is present in reverse index.
        previous_context_data = ObjectPath.get_path_value(
            step_context.active_dialog.state, QnAMakerDialog.KEY_QNA_CONTEXT_DATA, {}
        )
        previous_qna_id = ObjectPath.get_path_value(
            step_context.active_dialog.state, QnAMakerDialog.KEY_PREVIOUS_QNA_ID, 0
        )

        if previous_qna_id > 0:
            dialog_options.options.context = QnARequestContext(
                previous_qna_id=previous_qna_id
            )

            current_qna_id = previous_context_data.get(
                step_context.context.activity.text
            )
            if current_qna_id:
                dialog_options.options.qna_id = current_qna_id

        # Calling QnAMaker to get response.
        qna_client = self._get_qnamaker_client(step_context)
        response = await qna_client.get_answers_raw(
            step_context.context, dialog_options.options
        )

        is_active_learning_enabled = response.active_learning_enabled
        step_context.values[QnAMakerDialog.PROPERTY_QNA_DATA] = response.answers

        # Resetting previous query.
        previous_qna_id = -1
        ObjectPath.set_path_value(
            step_context.active_dialog.state,
            QnAMakerDialog.KEY_PREVIOUS_QNA_ID,
            previous_qna_id,
        )

        # Check if active learning is enabled and send card
        # maximum_score_for_low_score_variation is the score above which no need to check for feedback.
        if (
            response.answers
            and response.answers[0].score <= self.maximum_score_for_low_score_variation
        ):
            # Get filtered list of the response that support low score variation criteria.
            response.answers = qna_client.get_low_score_variation(response.answers)
            if len(response.answers) > 1 and is_active_learning_enabled:
                suggested_questions = [qna.questions[0] for qna in response.answers]
                message = QnACardBuilder.get_suggestions_card(
                    suggested_questions,
                    dialog_options.response_options.active_learning_card_title,
                    dialog_options.response_options.card_no_match_text,
                )
                await step_context.context.send_activity(message)

                ObjectPath.set_path_value(
                    step_context.active_dialog.state,
                    QnAMakerDialog.KEY_OPTIONS,
                    dialog_options,
                )

                await qna_client.close()

                return DialogTurnResult(DialogTurnStatus.Waiting)

        # If card is not shown, move to next step with top qna response.
        result = [response.answers[0]] if response.answers else []
        step_context.values[QnAMakerDialog.PROPERTY_QNA_DATA] = result
        ObjectPath.set_path_value(
            step_context.active_dialog.state, QnAMakerDialog.KEY_OPTIONS, dialog_options
        )

        await qna_client.close()

        return await step_context.next(result)