async def test_remove_path_value(self): test = {} ObjectPath.set_path_value(test, "x.y.z", 15) ObjectPath.set_path_value(test, "x.p", "hello") ObjectPath.set_path_value(test, "foo", {"Bar": 15, "Blat": "yo"}) ObjectPath.set_path_value(test, "x.a[1]", "yabba") ObjectPath.set_path_value(test, "x.a[0]", "dabba") ObjectPath.remove_path_value(test, "x.y.z") with self.assertRaises(KeyError): ObjectPath.get_path_value(test, "x.y.z") assert ObjectPath.get_path_value(test, "x.y.z", 99) == 99 ObjectPath.remove_path_value(test, "x.a[1]") assert not ObjectPath.try_get_path_value(test, "x.a[1]") assert ObjectPath.try_get_path_value(test, "x.a[0]") == "dabba"
async def test_set_value(self): test = {} ObjectPath.set_path_value(test, "x.y.z", 15) ObjectPath.set_path_value(test, "x.p", "hello") ObjectPath.set_path_value(test, "foo", {"Bar": 15, "Blat": "yo"}) ObjectPath.set_path_value(test, "x.a[1]", "yabba") ObjectPath.set_path_value(test, "x.a[0]", "dabba") ObjectPath.set_path_value(test, "null", None) assert ObjectPath.get_path_value(test, "x.y.z") == 15 assert ObjectPath.get_path_value(test, "x.p") == "hello" assert ObjectPath.get_path_value(test, "foo.bar") == 15 assert not ObjectPath.try_get_path_value(test, "foo.Blatxxx") assert ObjectPath.try_get_path_value(test, "x.a[1]") == "yabba" assert ObjectPath.try_get_path_value(test, "x.a[0]") == "dabba" assert not ObjectPath.try_get_path_value(test, "null")
async def __call_train(self, step_context: WaterfallStepContext): dialog_options: QnAMakerDialogOptions = ObjectPath.get_path_value( step_context.active_dialog.state, QnAMakerDialog.KEY_OPTIONS) train_responses: [ QueryResult ] = step_context.values[QnAMakerDialog.PROPERTY_QNA_DATA] current_query = step_context.values[ QnAMakerDialog.PROPERTY_CURRENT_QUERY] reply = step_context.context.activity.text if len(train_responses) > 1: qna_results = [ result for result in train_responses if result.questions[0] == reply ] if qna_results: qna_result = qna_results[0] step_context.values[QnAMakerDialog.PROPERTY_QNA_DATA] = [ qna_result ] feedback_records = [ FeedbackRecord( user_id=step_context.context.activity.id, user_question=current_query, qna_id=qna_result.id, ) ] # Call Active Learning Train API qna_client = self._get_qnamaker_client(step_context) await qna_client.call_train(feedback_records) await qna_client.close() return await step_context.next([qna_result]) if (reply.lower() == dialog_options.response_options. card_no_match_text.lower()): activity = dialog_options.response_options.card_no_match_response if not activity: await step_context.context.send_activity( QnAMakerDialog.DEFAULT_CARD_NO_MATCH_RESPONSE) else: await step_context.context.send_activity(activity) return await step_context.end_dialog() return await super().run_step(step_context, index=0, reason=DialogReason.BeginCalled, result=None) return await step_context.next(step_context.result)
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 __display_qna_result(self, step_context: WaterfallStepContext): dialog_options: QnAMakerDialogOptions = ObjectPath.get_path_value( step_context.active_dialog.state, QnAMakerDialog.KEY_OPTIONS ) reply = step_context.context.activity.text if reply.lower() == dialog_options.response_options.card_no_match_text.lower(): activity = dialog_options.response_options.card_no_match_response if not activity: await step_context.context.send_activity( QnAMakerDialog.DEFAULT_CARD_NO_MATCH_RESPONSE ) else: await step_context.context.send_activity(activity) return await step_context.end_dialog() # If previous QnAId is present, replace the dialog previous_qna_id = ObjectPath.get_path_value( step_context.active_dialog.state, QnAMakerDialog.KEY_PREVIOUS_QNA_ID, 0 ) if previous_qna_id > 0: return await super().run_step( step_context, index=0, reason=DialogReason.BeginCalled, result=None ) # If response is present then show that response, else default answer. response = step_context.result if response and isinstance(response, List): await step_context.context.send_activity(response[0].answer) else: activity = dialog_options.response_options.no_answer if not activity: await step_context.context.send_activity( QnAMakerDialog.DEFAULT_NO_ANSWER ) else: await step_context.context.send_activity(activity) return await step_context.end_dialog()
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)