コード例 #1
0
 def test_failed_and_not_abandoned(self):
     profile = UserProfile(validated=True)
     event = FailedPrompt(
         phone_number="123456789",
         user_profile=profile,
         prompt=DRILL.prompts[2],
         drill_instance_id=uuid.uuid4(),
         response="b",
         abandoned=False,
     )
     dialog_state = DialogState(
         "123456789",
         seq="0",
         user_profile=profile,
         current_drill=DRILL,
         drill_instance_id=event.drill_instance_id,
         current_prompt_state=PromptState(DRILL.prompts[2].slug,
                                          start_time=NOW),
     )
     event.apply_to(dialog_state)
     self.assertEqual(
         PromptState(
             slug=DRILL.prompts[2].slug,
             start_time=NOW,
             last_response_time=event.created_time,
             failures=1,
         ),
         dialog_state.current_prompt_state,
     )
コード例 #2
0
 def test_idempotence(self):
     user_id = self._make_user_and_get_id()
     event = DrillStarted(
         phone_number=self.phone_number,
         user_profile=UserProfile(True),
         drill=self.drill,
         first_prompt=self.prompt,
     )
     batch1 = self._make_batch([event])
     self.repo.update_user(batch1)
     user = self.repo.get_user(user_id)
     self.assertEqual(event.created_time, user.last_interacted_time)
     event2 = FailedPrompt(
         phone_number=self.phone_number,
         user_profile=UserProfile(True),
         prompt=self.prompt,
         drill_instance_id=event.drill_instance_id,
         response="go",
         abandoned=True,
     )
     batch2 = self._make_batch([event2])
     batch2.seq = batch1.seq
     self.repo.update_user(batch2)
     user = self.repo.get_user(user_id)
     self.assertEqual(event.created_time, user.last_interacted_time)
コード例 #3
0
 def test_failed_prompt(self):
     original = FailedPrompt(
         phone_number="123456789",
         user_profile=UserProfile(True),
         prompt=self.prompt,
         response="hello",
         abandoned=True,
         drill_instance_id=uuid.uuid4(),
     )
     serialized = original.to_dict()
     deserialized: FailedPrompt = event_from_dict(
         serialized)  # type: ignore
     self._make_base_assertions(original, deserialized)
     self.assertEqual(original.prompt.slug, deserialized.prompt.slug)
     for original_message, deserialized_message in zip(
             original.prompt.messages, deserialized.prompt.messages):
         self.assertEqual(original_message.text, deserialized_message.text)
         self.assertEqual(original_message.media_url,
                          deserialized_message.media_url)
     self.assertEqual(original.response, deserialized.response)
     self.assertEqual(original.abandoned, deserialized.abandoned)
     self.assertEqual(original.drill_instance_id,
                      deserialized.drill_instance_id)
コード例 #4
0
    def _check_response(
        self, dialog_state: DialogState, base_args: Dict[str, Any]
    ) -> Optional[List[stopcovid.dialog.models.events.DialogEvent]]:
        prompt = dialog_state.get_prompt()
        if prompt is None:
            return
        events = []
        if prompt.should_advance_with_answer(
                self.content_lower, dialog_state.user_profile.language):
            events.append(
                CompletedPrompt(
                    prompt=prompt,
                    drill_instance_id=dialog_state.
                    drill_instance_id,  # type: ignore
                    response=self.content,
                    **base_args,
                ))
            should_advance = True
        else:
            should_advance = dialog_state.current_prompt_state.failures >= prompt.max_failures
            events.append(
                FailedPrompt(
                    prompt=prompt,
                    response=self.content,
                    drill_instance_id=dialog_state.
                    drill_instance_id,  # type: ignore
                    abandoned=should_advance,
                    **base_args,
                ))

        if should_advance:
            next_prompt = dialog_state.get_next_prompt()
            if next_prompt is not None:
                events.append(
                    AdvancedToNextPrompt(
                        prompt=next_prompt,
                        drill_instance_id=dialog_state.
                        drill_instance_id,  # type: ignore
                        **base_args,
                    ))
                if dialog_state.is_next_prompt_last():
                    # assume the last prompt doesn't wait for an answer
                    events.append(
                        DrillCompleted(
                            drill_instance_id=dialog_state.
                            drill_instance_id,  # type: ignore
                            **base_args,
                        ))
        return events
コード例 #5
0
 def test_prompt_failed(self):
     self.repo._save_drill_instance(self.drill_instance)
     event = FailedPrompt(
         phone_number=self.phone_number,
         user_profile=UserProfile(True),
         prompt=self.prompt1,
         drill_instance_id=self.drill_instance.drill_instance_id,
         response="go",
         abandoned=False,
     )
     self.repo.update_user(self._make_batch([event]))
     retrieved = self.repo.get_drill_instance(
         self.drill_instance.drill_instance_id)
     self.assertEqual(event.created_time,
                      retrieved.current_prompt_last_response_time)
コード例 #6
0
 def test_non_abandoned_failed_prompt_event(self):
     dialog_events: List[DialogEvent] = [
         FailedPrompt(
             phone_number=self.phone,
             user_profile=self.validated_user_profile,
             prompt=self.drill.prompts[1],
             response="a",
             drill_instance_id=uuid.uuid4(),
             abandoned=False,
         )
     ]
     outbound_messages = get_outbound_sms_commands(dialog_events)
     self.assertEqual(len(outbound_messages), 1)
     message = outbound_messages[0]
     self.assertEqual(message.phone_number, self.phone)
     self.assertEqual(message.event_id, dialog_events[0].event_id)
     self.assertEqual(message.body,
                      "🤖 Sorry, not correct. Try again one more time.")
コード例 #7
0
    def test_abandoned_failed_prompt_event(self):

        dialog_events: List[DialogEvent] = [
            FailedPrompt(
                self.phone,
                self.validated_user_profile,
                prompt=self.drill.prompts[1],
                response="a",
                drill_instance_id=uuid.uuid4(),
                abandoned=True,
            )
        ]
        outbound_messages = get_outbound_sms_commands(dialog_events)
        self.assertEqual(len(outbound_messages), 1)
        message = outbound_messages[0]
        self.assertEqual(message.phone_number, self.phone)
        self.assertEqual(message.event_id, dialog_events[0].event_id)
        self.assertEqual(
            message.body,
            "🤖 The correct answer is *a*.\n\nLets move to the next one.")
コード例 #8
0
ファイル: engine.py プロジェクト: opus-training/dialog-engine
    def _check_response(
            self, dialog_state: DialogState,
            base_args: Dict[str, Any]) -> Optional[List[DialogEvent]]:
        prompt = dialog_state.get_prompt()
        if prompt is None:
            return None
        events: List[DialogEvent] = []
        if prompt.should_advance_with_answer(self.content_lower):
            user_profile_updates = None
            if prompt.response_user_profile_key:
                user_profile_updates = {
                    prompt.response_user_profile_key: self.content
                }
            events.append(
                CompletedPrompt(
                    prompt=prompt,
                    drill_instance_id=dialog_state.drill_instance_id,
                    response=self.content,
                    user_profile_updates=user_profile_updates,
                    **base_args,
                ))
            should_advance = True
        else:
            assert dialog_state.current_prompt_state
            should_advance = dialog_state.current_prompt_state.failures >= (
                prompt.max_failures or 1)
            events.append(
                FailedPrompt(
                    prompt=prompt,
                    response=self.content or None,
                    drill_instance_id=dialog_state.drill_instance_id,
                    abandoned=should_advance,
                    **base_args,
                ))

        if should_advance:
            assert dialog_state.current_drill
            next_prompt = dialog_state.get_next_prompt()
            if next_prompt is not None:
                events.append(
                    AdvancedToNextPrompt(
                        prompt=next_prompt,
                        drill_instance_id=dialog_state.drill_instance_id,
                        **base_args,
                    ))
                if dialog_state.is_next_prompt_last():
                    # assume the last prompt doesn't wait for an answer
                    events.append(
                        DrillCompleted(
                            drill_instance_id=dialog_state.drill_instance_id,
                            **base_args,
                        ))
            elif len(dialog_state.current_drill.prompts) == 1:
                events.append(
                    DrillCompleted(
                        drill_instance_id=dialog_state.drill_instance_id,
                        last_prompt_response=self.content or None,
                        **base_args,
                    ))

        return events