def test_legacy_protocol(self): v3_hostname = "https://westus.api.cognitive.microsoft.com/qnamaker/v3.0" v3_legacy_endpoint = QnAMakerEndpoint(self._knowledge_base_id, self._endpoint_key, v3_hostname) legacy_qna = QnAMaker(v3_legacy_endpoint) is_legacy = True v4_hostname = "https://UpdatedNonLegacyQnaHostName.azurewebsites.net/qnamaker" nonlegacy_endpoint = QnAMakerEndpoint(self._knowledge_base_id, self._endpoint_key, v4_hostname) v4_qna = QnAMaker(nonlegacy_endpoint) self.assertEqual(is_legacy, legacy_qna._is_legacy_protocol) self.assertNotEqual(is_legacy, v4_qna._is_legacy_protocol)
def test_options_passed_to_ctor(self): options = QnAMakerOptions( score_threshold=0.8, timeout=9000, top=5, strict_filters=[Metadata("movie", "disney")], ) qna_with_options = QnAMaker(self.tests_endpoint, options) actual_options = qna_with_options._generate_answer_helper.options expected_threshold = 0.8 expected_timeout = 9000 expected_top = 5 expected_strict_filters = [Metadata("movie", "disney")] self.assertEqual(expected_threshold, actual_options.score_threshold) self.assertEqual(expected_timeout, actual_options.timeout) self.assertEqual(expected_top, actual_options.top) self.assertEqual( expected_strict_filters[0].name, actual_options.strict_filters[0].name ) self.assertEqual( expected_strict_filters[0].value, actual_options.strict_filters[0].value )
def __init__(self, config: DefaultConfig): self.qna_maker = QnAMaker( QnAMakerEndpoint( knowledge_base_id=config.QNA_KNOWLEDGEBASE_ID, endpoint_key=config.QNA_ENDPOINT_KEY, host=config.QNA_ENDPOINT_HOST, ))
def __init__(self, config: Config): self.qna_maker = QnAMaker( QnAMakerEndpoint( knowledge_base_id=config["QNA_KNOWLEDGEBASE_ID"], endpoint_key=config["QNA_ENDPOINT_KEY"], host=config["QNA_ENDPOINT_HOST"], ))
def __init__(self, user_state: UserState, luis_recognizer: InsuranceQueryRecognizer, insurance_renewal_dialog: InsuranceRenewalDialog, reservation_booking_dialog: ReservationBookingDialog): super(MainDialog, self).__init__(MainDialog.__name__) self.qna_maker = QnAMaker( QnAMakerEndpoint(knowledge_base_id=config.QNA_KNOWLEDGEBASE_ID, endpoint_key=config.QNA_ENDPOINT_KEY, host=config.QNA_ENDPOINT_HOST)) self.user_profile_accessor = user_state.create_property("UserData") self.insurance_renewal_dialog_id = insurance_renewal_dialog.id self.reservation_booking_dialog_id = reservation_booking_dialog.id self._luis_recognizer = luis_recognizer self.user_state = user_state self.add_dialog(TextPrompt(TextPrompt.__name__)) self.add_dialog(ChoicePrompt(INS_PROMPT_OPTIONS)) self.add_dialog(insurance_renewal_dialog) self.add_dialog(reservation_booking_dialog) self.add_dialog( WaterfallDialog("WFDialog", [ self.intro_step, self.name_process_step, self.luis_query_step, self.closing_step ])) self.initial_dialog_id = "WFDialog"
def __init__(self, config: DefaultConfig, conversation_state: ConversationState, user_state: UserState, promptInput=False, getClaim=False): self.qna_maker = QnAMaker( QnAMakerEndpoint( knowledge_base_id=config.QNA_KNOWLEDGEBASE_ID, endpoint_key=config.QNA_ENDPOINT_KEY, host=config.QNA_ENDPOINT_HOST, )) self.promptInput = promptInput self.getClaim = getClaim if conversation_state is None: raise TypeError( "[CustomPromptBot]: Missing parameter. conversation_state is required but None was given" ) if user_state is None: raise TypeError( "[CustomPromptBot]: Missing parameter. user_state is required but None was given" ) self.conversation_state = conversation_state self.user_state = user_state self.flow_accessor = self.conversation_state.create_property( "ConversationFlow") self.profile_accessor = self.user_state.create_property("UserProfile") self.flow_accessor = self.conversation_state.create_property( "ConversationFlow") self.profile_accessor = self.user_state.create_property("UserProfile")
def __init__(self, user_state: UserState, config: Config): self.qna_maker = QnAMaker( QnAMakerEndpoint( knowledge_base_id=config.QNA_KNOWLEDGEBASE_ID, endpoint_key=config.QNA_ENDPOINT_KEY, host=config.QNA_ENDPOINT_HOST, )) if user_state is None: raise TypeError( "[WelcomeUserBot]: Missing parameter. user_state is required but None was given" ) self._user_state = user_state self.user_state_accessor = self._user_state.create_property( "WelcomeUserState") self.WELCOME_MESSAGE = """Type 'hello', 'hi','bye', 'docs' and 'intro' to explore more. Try it now, type 'hi'""" self.INFO_MESSAGE = """Welcome to ADC CHAT BOT""" self.LOCALE_MESSAGE = """" """ self.PATTERN_MESSAGE = """Type 'hello', 'hi','bye', 'docs' and 'intro' to explore more. Try it now, type 'hi'"""
def test_v2_legacy_endpoint(self): v2_hostname = "https://westus.api.cognitive.microsoft.com/qnamaker/v2.0" v2_legacy_endpoint = QnAMakerEndpoint(self._knowledge_base_id, self._endpoint_key, v2_hostname) with self.assertRaises(ValueError): QnAMaker(v2_legacy_endpoint)
async def test_call_train(self): feedback_records = [] feedback1 = FeedbackRecord( qna_id=1, user_id="test", user_question="How are you?" ) feedback2 = FeedbackRecord(qna_id=2, user_id="test", user_question="What up??") feedback_records.extend([feedback1, feedback2]) with patch.object( QnAMaker, "call_train", return_value=None ) as mocked_call_train: qna = QnAMaker(QnaApplicationTest.tests_endpoint) qna.call_train(feedback_records) mocked_call_train.assert_called_once_with(feedback_records)
async def test_telemetry_additional_props_metrics(self): # Arrange question: str = 'how do I clean the stove?' response_json = QnaApplicationTest._get_json_for_file( 'ReturnsAnswer.json') context = QnaApplicationTest._get_context(question, TestAdapter()) options = QnAMakerOptions(top=1) telemetry_client = unittest.mock.create_autospec(BotTelemetryClient) log_personal_information = False # Act with patch('aiohttp.ClientSession.post', return_value=aiounittest.futurized(response_json)): qna = QnAMaker(QnaApplicationTest.tests_endpoint, options, None, telemetry_client, log_personal_information) telemetry_properties: Dict[str, str] = { 'my_important_property': 'my_important_value' } telemetry_metrics: Dict[str, float] = { 'my_important_metric': 3.14159 } results = await qna.get_answers(context, None, telemetry_properties, telemetry_metrics) # Assert - Added properties were added. telemetry_args = telemetry_client.track_event.call_args_list[0][1] telemetry_properties = telemetry_args['properties'] expected_answer = 'BaseCamp: You can use a damp rag to clean around the Power Pack' self.assertEqual(1, telemetry_client.track_event.call_count) self.assertEqual(3, len(telemetry_args)) self.assertEqual('QnaMessage', telemetry_args['name']) self.assertTrue('knowledgeBaseId' in telemetry_properties) self.assertTrue('question' not in telemetry_properties) self.assertTrue('matchedQuestion' in telemetry_properties) self.assertTrue('questionId' in telemetry_properties) self.assertTrue('answer' in telemetry_properties) self.assertTrue(expected_answer, telemetry_properties['answer'][0]) self.assertTrue('my_important_property' in telemetry_properties) self.assertEqual('my_important_value', telemetry_properties['my_important_property']) tracked_metrics = telemetry_args['measurements'] self.assertEqual(2, len(tracked_metrics)) self.assertTrue('score' in tracked_metrics) self.assertTrue('my_important_metric' in tracked_metrics) self.assertEqual(3.14159, tracked_metrics['my_important_metric']) # Assert - Validate we didn't break QnA functionality. self.assertIsNotNone(results) self.assertEqual(1, len(results)) self.assertEqual(expected_answer, results[0].answer[0]) self.assertEqual('Editorial', results[0].source)
async def test_telemetry_additional_props_override(self): question: str = 'how do I clean the stove?' response_json = QnaApplicationTest._get_json_for_file( 'ReturnsAnswer.json') context = QnaApplicationTest._get_context(question, TestAdapter()) options = QnAMakerOptions(top=1) telemetry_client = unittest.mock.create_autospec(BotTelemetryClient) log_personal_information = False # Act - Pass in properties during QnA invocation that override default properties # NOTE: We are invoking this with PII turned OFF, and passing a PII property (originalQuestion). qna = QnAMaker(QnaApplicationTest.tests_endpoint, options, None, telemetry_client, log_personal_information) telemetry_properties = { 'knowledge_base_id': 'my_important_value', 'original_question': 'my_important_value2' } telemetry_metrics = {'score': 3.14159} with patch('aiohttp.ClientSession.post', return_value=aiounittest.futurized(response_json)): results = await qna.get_answers(context, None, telemetry_properties, telemetry_metrics) # Assert - Added properties were added. tracked_args = telemetry_client.track_event.call_args_list[0][1] tracked_properties = tracked_args['properties'] expected_answer = 'BaseCamp: You can use a damp rag to clean around the Power Pack' tracked_metrics = tracked_args['measurements'] self.assertEqual(1, telemetry_client.track_event.call_count) self.assertEqual(3, len(tracked_args)) self.assertEqual('QnaMessage', tracked_args['name']) self.assertTrue('knowledge_base_id' in tracked_properties) self.assertEqual('my_important_value', tracked_properties['knowledge_base_id']) self.assertTrue('original_question' in tracked_properties) self.assertTrue('matchedQuestion' in tracked_properties) self.assertEqual('my_important_value2', tracked_properties['original_question']) self.assertTrue('question' not in tracked_properties) self.assertTrue('questionId' in tracked_properties) self.assertTrue('answer' in tracked_properties) self.assertEqual(expected_answer, tracked_properties['answer'][0]) self.assertTrue('my_important_property' not in tracked_properties) self.assertEqual(1, len(tracked_metrics)) self.assertTrue('score' in tracked_metrics) self.assertEqual(3.14159, tracked_metrics['score']) # Assert - Validate we didn't break QnA functionality. self.assertIsNotNone(results) self.assertEqual(1, len(results)) self.assertEqual(expected_answer, results[0].answer[0]) self.assertEqual('Editorial', results[0].source)
async def test_should_filter_low_score_variation(self): options = QnAMakerOptions(top=5) qna = QnAMaker(QnaApplicationTest.tests_endpoint, options) question: str = "Q11" context = QnaApplicationTest._get_context(question, TestAdapter()) response_json = QnaApplicationTest._get_json_for_file("TopNAnswer.json") with patch( "aiohttp.ClientSession.post", return_value=aiounittest.futurized(response_json), ): results = await qna.get_answers(context) self.assertEqual(4, len(results), "Should have received 4 answers.") filtered_results = qna.get_low_score_variation(results) self.assertEqual( 3, len(filtered_results), "Should have 3 filtered answers after low score variation.", )
def test_set_default_options_with_no_options_arg(self): qna_without_options = QnAMaker(self.tests_endpoint) options = qna_without_options._generate_answer_helper.options default_threshold = 0.3 default_top = 1 default_strict_filters = [] self.assertEqual(default_threshold, options.score_threshold) self.assertEqual(default_top, options.top) self.assertEqual(default_strict_filters, options.strict_filters)
async def test_low_score_variation(self): qna = QnAMaker(QnaApplicationTest.tests_endpoint) options = QnAMakerOptions(top=5, context=None) turn_context = QnaApplicationTest._get_context("Q11", TestAdapter()) response_json = QnaApplicationTest._get_json_for_file( "QnaMaker_TopNAnswer.json") # active learning enabled with patch( "aiohttp.ClientSession.post", return_value=aiounittest.futurized(response_json), ): results = await qna.get_answers(turn_context, options) self.assertIsNotNone(results) self.assertEqual(4, len(results), "should get four results") filtered_results = qna.get_low_score_variation(results) self.assertIsNotNone(filtered_results) self.assertEqual(3, len(filtered_results), "should get three results") # active learning disabled turn_context = QnaApplicationTest._get_context("Q11", TestAdapter()) response_json = QnaApplicationTest._get_json_for_file( "QnaMaker_TopNAnswer_DisableActiveLearning.json") with patch( "aiohttp.ClientSession.post", return_value=aiounittest.futurized(response_json), ): results = await qna.get_answers(turn_context, options) self.assertIsNotNone(results) self.assertEqual(4, len(results), "should get four results") filtered_results = qna.get_low_score_variation(results) self.assertIsNotNone(filtered_results) self.assertEqual(3, len(filtered_results), "should get three results")
async def test_returns_answer_with_timeout(self): question: str = 'how do I clean the stove?' options = QnAMakerOptions(timeout=999999) qna = QnAMaker(QnaApplicationTest.tests_endpoint, options) context = QnaApplicationTest._get_context(question, TestAdapter()) response_json = QnaApplicationTest._get_json_for_file( 'ReturnsAnswer.json') with patch('aiohttp.ClientSession.post', return_value=aiounittest.futurized(response_json)): result = await qna.get_answers(context, options) self.assertIsNotNone(result) self.assertEqual(options.timeout, qna._options.timeout)
async def test_telemetry_pii(self): # Arrange question: str = "how do I clean the stove?" response_json = QnaApplicationTest._get_json_for_file( "ReturnsAnswer.json") telemetry_client = unittest.mock.create_autospec(BotTelemetryClient) log_personal_information = False context = QnaApplicationTest._get_context(question, TestAdapter()) qna = QnAMaker( QnaApplicationTest.tests_endpoint, telemetry_client=telemetry_client, log_personal_information=log_personal_information, ) # Act with patch( "aiohttp.ClientSession.post", return_value=aiounittest.futurized(response_json), ): results = await qna.get_answers(context) telemetry_args = telemetry_client.track_event.call_args_list[0][1] telemetry_properties = telemetry_args["properties"] telemetry_metrics = telemetry_args["measurements"] number_of_args = len(telemetry_args) first_answer = telemetry_args["properties"][ QnATelemetryConstants.answer_property] expected_answer = ( "BaseCamp: You can use a damp rag to clean around the Power Pack" ) # Assert - Validate PII properties not logged. self.assertEqual(1, telemetry_client.track_event.call_count) self.assertEqual(3, number_of_args) self.assertEqual("QnaMessage", telemetry_args["name"]) self.assertTrue("answer" in telemetry_properties) self.assertTrue("knowledgeBaseId" in telemetry_properties) self.assertTrue("matchedQuestion" in telemetry_properties) self.assertTrue("question" not in telemetry_properties) self.assertTrue("questionId" in telemetry_properties) self.assertTrue("articleFound" in telemetry_properties) self.assertEqual(expected_answer, first_answer) self.assertTrue("score" in telemetry_metrics) self.assertEqual(1, telemetry_metrics["score"]) # Assert - Validate we didn't break QnA functionality. self.assertIsNotNone(results) self.assertEqual(1, len(results)) self.assertEqual(expected_answer, results[0].answer) self.assertEqual("Editorial", results[0].source)
async def _get_service_result(cls, utterance: str, response_file: str, bot_adapter: BotAdapter = TestAdapter(), options: QnAMakerOptions = None) -> [dict]: response_json = QnaApplicationTest._get_json_for_file(response_file) qna = QnAMaker(QnaApplicationTest.tests_endpoint) context = QnaApplicationTest._get_context(utterance, bot_adapter) with patch('aiohttp.ClientSession.post', return_value=aiounittest.futurized(response_json)): result = await qna.get_answers(context, options) return result
def test_qnamaker_construction(self): # Arrange endpoint = self.tests_endpoint # Act qna = QnAMaker(endpoint) endpoint = qna._endpoint # Assert self.assertEqual("f028d9k3-7g9z-11d3-d300-2b8x98227q8w", endpoint.knowledge_base_id) self.assertEqual("1k997n7w-207z-36p3-j2u1-09tas20ci6011", endpoint.endpoint_key) self.assertEqual("https://dummyqnahost.azurewebsites.net/qnamaker", endpoint.host)
async def test_should_answer_with_ranker_type_question_only(self): options = QnAMakerOptions(top=1, ranker_type="QuestionOnly") qna = QnAMaker(QnaApplicationTest.tests_endpoint) question: str = "Q11" context = QnaApplicationTest._get_context(question, TestAdapter()) response_json = QnaApplicationTest._get_json_for_file( "QnaMaker_RankerType_QuestionOnly.json") with patch( "aiohttp.ClientSession.post", return_value=aiounittest.futurized(response_json), ): results = await qna.get_answers(context, options=options) self.assertEqual(2, len(results), "Should have received two answers.")
async def test_should_answer_with_is_test_true(self): options = QnAMakerOptions(top=1, is_test=True) qna = QnAMaker(QnaApplicationTest.tests_endpoint) question: str = "Q11" context = QnaApplicationTest._get_context(question, TestAdapter()) response_json = QnaApplicationTest._get_json_for_file( "QnaMaker_IsTest_true.json") with patch( "aiohttp.ClientSession.post", return_value=aiounittest.futurized(response_json), ): results = await qna.get_answers(context, options=options) self.assertEqual(0, len(results), "Should have received zero answer.")
async def test_telemetry_returns_answer_when_no_answer_found_in_kb(self): # Arrange question: str = "gibberish question" response_json = QnaApplicationTest._get_json_for_file( "NoAnswerFoundInKb.json") telemetry_client = unittest.mock.create_autospec(BotTelemetryClient) qna = QnAMaker( QnaApplicationTest.tests_endpoint, telemetry_client=telemetry_client, log_personal_information=True, ) context = QnaApplicationTest._get_context(question, TestAdapter()) # Act with patch( "aiohttp.ClientSession.post", return_value=aiounittest.futurized(response_json), ): results = await qna.get_answers(context) telemetry_args = telemetry_client.track_event.call_args_list[0][1] telemetry_properties = telemetry_args["properties"] number_of_args = len(telemetry_args) first_answer = telemetry_args["properties"][ QnATelemetryConstants.answer_property] expected_answer = "No Qna Answer matched" expected_matched_question = "No Qna Question matched" # Assert - Check Telemetry logged. self.assertEqual(1, telemetry_client.track_event.call_count) self.assertEqual(3, number_of_args) self.assertEqual("QnaMessage", telemetry_args["name"]) self.assertTrue("answer" in telemetry_properties) self.assertTrue("knowledgeBaseId" in telemetry_properties) self.assertTrue("matchedQuestion" in telemetry_properties) self.assertEqual( expected_matched_question, telemetry_properties[ QnATelemetryConstants.matched_question_property], ) self.assertTrue("question" in telemetry_properties) self.assertTrue("questionId" in telemetry_properties) self.assertTrue("articleFound" in telemetry_properties) self.assertEqual(expected_answer, first_answer) # Assert - Validate we didn't break QnA functionality. self.assertIsNotNone(results) self.assertEqual(0, len(results))
async def test_should_answer_with_prompts(self): options = QnAMakerOptions(top=2) qna = QnAMaker(QnaApplicationTest.tests_endpoint, options) question: str = "how do I clean the stove?" turn_context = QnaApplicationTest._get_context(question, TestAdapter()) response_json = QnaApplicationTest._get_json_for_file("AnswerWithPrompts.json") with patch( "aiohttp.ClientSession.post", return_value=aiounittest.futurized(response_json), ): results = await qna.get_answers(turn_context, options) self.assertEqual(1, len(results), "Should have received 1 answers.") self.assertEqual( 1, len(results[0].context.prompts), "Should have received 1 prompt." )
def test_qnamaker_construction(self): # Arrange endpoint = self.tests_endpoint # Act qna = QnAMaker(endpoint) endpoint = qna._endpoint # Assert self.assertEqual('a090f9f3-2f8e-41d1-a581-4f7a49269a0c', endpoint.knowledge_base_id) self.assertEqual('4a439d5b-163b-47c3-b1d1-168cc0db5608', endpoint.endpoint_key) self.assertEqual( 'https://ashleyNlpBot1-qnahost.azurewebsites.net/qnamaker', endpoint.host)
async def test_returns_answer_with_strict_filters_with_and_operator(self): # Arrange question: str = "Where can you find" response_path: str = "RetrunsAnswer_WithStrictFilter_And_Operator.json" response_json = QnaApplicationTest._get_json_for_file(response_path) strict_filters = [ Metadata(name="species", value="human"), Metadata(name="type", value="water"), ] options = QnAMakerOptions( top=5, strict_filters=strict_filters, strict_filters_join_operator=JoinOperator.AND, ) qna = QnAMaker(endpoint=QnaApplicationTest.tests_endpoint) context = QnaApplicationTest._get_context(question, TestAdapter()) # Act with patch( "aiohttp.ClientSession.post", return_value=aiounittest.futurized(response_json), ) as mock_http_client: result = await qna.get_answers_raw(context, options) serialized_http_req_args = mock_http_client.call_args[1]["data"] req_args = json.loads(serialized_http_req_args) # Assert self.assertIsNotNone(result) self.assertEqual(1, len(result.answers)) self.assertEqual(JoinOperator.AND, req_args["strictFiltersCompoundOperationType"]) req_args_strict_filters = req_args["strictFilters"] first_filter = strict_filters[0] self.assertEqual(first_filter.name, req_args_strict_filters[0]["name"]) self.assertEqual(first_filter.value, req_args_strict_filters[0]["value"]) second_filter = strict_filters[1] self.assertEqual(second_filter.name, req_args_strict_filters[1]["name"]) self.assertEqual(second_filter.value, req_args_strict_filters[1]["value"])
async def test_should_answer_with_high_score_provided_qna_id(self): qna = QnAMaker(QnaApplicationTest.tests_endpoint) question: str = "where can I buy?" options = QnAMakerOptions(top=2, qna_id=55) turn_context = QnaApplicationTest._get_context(question, TestAdapter()) response_json = QnaApplicationTest._get_json_for_file( "AnswerWithHighScoreProvidedContext.json") with patch( "aiohttp.ClientSession.post", return_value=aiounittest.futurized(response_json), ): results = await qna.get_answers(turn_context, options) self.assertEqual(1, len(results), "Should have received 1 answers.") self.assertEqual(1, results[0].score, "Score should be high.")
def __init__(self, conversation_state: ConversationState, user_state: UserState): self.config_reader = ConfigReader() self.configuration = self.config_reader.read_config() self.luis_app_id = self.configuration['LUIS_APP_ID'] self.luis_endpoint_key = self.configuration['LUIS_ENDPOINT_KEY'] self.luis_endpoint = self.configuration['LUIS_ENDPOINT'] self.luis_app = LuisApplication(self.luis_app_id, self.luis_endpoint_key, self.luis_endpoint) self.luis_options = LuisPredictionOptions(include_all_intents=True, include_instance_data=True) self.luis_recognizer = LuisRecognizer( application=self.luis_app, prediction_options=self.luis_options, include_api_results=True) self.qna_knowledge_base_id = self.configuration["QNA_KNOWLEDGEBASE_ID"] self.qna_endpoint_key = self.configuration["QNA_ENDPOINT_KEY"] self.qna_host = self.configuration["QNA_ENDPOINT_HOST"] self.qna_maker = QnAMaker( QnAMakerEndpoint(knowledge_base_id=self.qna_knowledge_base_id, endpoint_key=self.qna_endpoint_key, host=self.qna_host)) self.log = Log() self.IntentIdentified = False self.intent = 'none' self.stat = 'init' self.city = "" self.score = "" if conversation_state is None: raise TypeError( "[StateManagementBot]: Missing parameter. conversation_state is required but None was given" ) if user_state is None: raise TypeError( "[StateManagementBot]: Missing parameter. user_state is required but None was given" ) self.conversation_state = conversation_state self.user_state = user_state self.conversation_data_accessor = self.conversation_state.create_property( "ConversationData") self.user_profile_accessor = self.user_state.create_property( "UserProfile")
async def test_trace_test(self): activity = Activity( type=ActivityTypes.message, text="how do I clean the stove?", conversation=ConversationAccount(), recipient=ChannelAccount(), from_property=ChannelAccount(), ) response_json = QnaApplicationTest._get_json_for_file( "ReturnsAnswer.json") qna = QnAMaker(QnaApplicationTest.tests_endpoint) context = TestContext(activity) with patch( "aiohttp.ClientSession.post", return_value=aiounittest.futurized(response_json), ): result = await qna.get_answers(context) qna_trace_activities = list( filter( lambda act: act.type == "trace" and act.name == "QnAMaker", context.sent, )) trace_activity = qna_trace_activities[0] self.assertEqual("trace", trace_activity.type) self.assertEqual("QnAMaker", trace_activity.name) self.assertEqual("QnAMaker Trace", trace_activity.label) self.assertEqual("https://www.qnamaker.ai/schemas/trace", trace_activity.value_type) self.assertEqual(True, hasattr(trace_activity, "value")) self.assertEqual(True, hasattr(trace_activity.value, "message")) self.assertEqual(True, hasattr(trace_activity.value, "query_results")) self.assertEqual(True, hasattr(trace_activity.value, "score_threshold")) self.assertEqual(True, hasattr(trace_activity.value, "top")) self.assertEqual(True, hasattr(trace_activity.value, "strict_filters")) self.assertEqual(self._knowledge_base_id, trace_activity.value.knowledge_base_id) return result
async def test_should_answer_with_low_score_without_provided_context(self): qna = QnAMaker(QnaApplicationTest.tests_endpoint) question: str = "where can I buy?" options = QnAMakerOptions(top=2, context=None) turn_context = QnaApplicationTest._get_context(question, TestAdapter()) response_json = QnaApplicationTest._get_json_for_file( "AnswerWithLowScoreProvidedWithoutContext.json") with patch( "aiohttp.ClientSession.post", return_value=aiounittest.futurized(response_json), ): results = await qna.get_answers(turn_context, options) self.assertEqual(2, len(results), "Should have received more than one answers.") self.assertEqual(True, results[0].score < 1, "Score should be low.")
def __init__(self, config: DefaultConfig): self.qna_maker = QnAMaker( QnAMakerEndpoint( knowledge_base_id=config.QNA_KNOWLEDGEBASE_ID, endpoint_key=config.QNA_ENDPOINT_KEY, host=config.QNA_ENDPOINT_HOST, )) # If the includeApiResults parameter is set to true, as shown below, the full response # from the LUIS api will be made available in the properties of the RecognizerResult luis_application = LuisApplication( config.LUIS_APP_ID, config.LUIS_API_KEY, "https://" + config.LUIS_API_HOST_NAME, ) luis_options = LuisPredictionOptions(include_all_intents=True, include_instance_data=True) self.recognizer = LuisRecognizer(luis_application, luis_options, True)
async def test_telemetry_returns_answer(self): # Arrange question: str = 'how do I clean the stove?' response_json = QnaApplicationTest._get_json_for_file( 'ReturnsAnswer.json') telemetry_client = unittest.mock.create_autospec(BotTelemetryClient) log_personal_information = True context = QnaApplicationTest._get_context(question, TestAdapter()) qna = QnAMaker(QnaApplicationTest.tests_endpoint, telemetry_client=telemetry_client, log_personal_information=log_personal_information) # Act with patch('aiohttp.ClientSession.post', return_value=aiounittest.futurized(response_json)): results = await qna.get_answers(context) telemetry_args = telemetry_client.track_event.call_args_list[0][1] telemetry_properties = telemetry_args['properties'] telemetry_metrics = telemetry_args['measurements'] number_of_args = len(telemetry_args) first_answer = telemetry_args['properties'][ QnATelemetryConstants.answer_property][0] expected_answer = 'BaseCamp: You can use a damp rag to clean around the Power Pack' # Assert - Check Telemetry logged. self.assertEqual(1, telemetry_client.track_event.call_count) self.assertEqual(3, number_of_args) self.assertEqual('QnaMessage', telemetry_args['name']) self.assertTrue('answer' in telemetry_properties) self.assertTrue('knowledgeBaseId' in telemetry_properties) self.assertTrue('matchedQuestion' in telemetry_properties) self.assertTrue('question' in telemetry_properties) self.assertTrue('questionId' in telemetry_properties) self.assertTrue('articleFound' in telemetry_properties) self.assertEqual(expected_answer, first_answer) self.assertTrue('score' in telemetry_metrics) self.assertEqual(1, telemetry_metrics['score'][0]) # Assert - Validate we didn't break QnA functionality. self.assertIsNotNone(results) self.assertEqual(1, len(results)) self.assertEqual(expected_answer, results[0].answer[0]) self.assertEqual('Editorial', results[0].source)