def add_events(self, events: List[Event]) -> None: """Adds next story steps with the specified list of events. Args: events: Events that need to be added. """ self.ensure_current_steps() if len(events) == 1: # If there is only one possible event, we'll keep things simple for t in self.current_steps: t.add_event(events[0]) else: # If there are multiple different events the # user can use the express the same thing # we need to copy the blocks and create one # copy for each possible message generated_checkpoint = self._generate_checkpoint_name_for_or_statement( events) updated_steps = [] for t in self.current_steps: for event in events: copied = t.create_copy(use_new_id=True) copied.add_event(event) copied.end_checkpoints = [Checkpoint(generated_checkpoint)] updated_steps.append(copied) self.current_steps = updated_steps
def _prev_end_checkpoints(self) -> List[Checkpoint]: if not self.current_steps: return self.start_checkpoints else: # makes sure we got each end name only once end_names = {e.name for s in self.current_steps for e in s.end_checkpoints} return [Checkpoint(name) for name in end_names]
def _next_story_steps(self) -> List[StoryStep]: start_checkpoints = self._prev_end_checkpoints() if not start_checkpoints: start_checkpoints = [Checkpoint(STORY_START)] step_class = RuleStep if self.is_rule else StoryStep current_turns = [ step_class( block_name=self.name, start_checkpoints=start_checkpoints, source_name=self.source_name, ) ] return current_turns
def add_checkpoint(self, name: Text, conditions: Optional[Dict[Text, Any]]) -> None: # Depending on the state of the story part this # is either a start or an end check point if not self.current_steps: self.start_checkpoints.append(Checkpoint(name, conditions)) else: if conditions: rasa.shared.utils.io.raise_warning( f"End or intermediate checkpoints " f"do not support conditions! " f"(checkpoint: {name})", docs=DOCS_URL_STORIES + "#checkpoints", ) additional_steps = [] for t in self.current_steps: if t.end_checkpoints: tcp = t.create_copy(use_new_id=True) tcp.end_checkpoints = [Checkpoint(name)] additional_steps.append(tcp) else: t.end_checkpoints = [Checkpoint(name)] self.current_steps.extend(additional_steps)
def add_user_messages( self, messages: List[UserUttered], is_used_for_conversion: bool = False ) -> None: """Adds next story steps with the user's utterances. Args: messages: User utterances. is_used_for_conversion: Identifies if the user utterance is a part of OR statement. This parameter is used only to simplify the conversation from MD story files. Don't use it other ways, because it ends up in a invalid story that cannot be user for real training. Default value is `False`, which preserves the expected behavior of the reader. """ self.ensure_current_steps() if len(messages) == 1: # If there is only one possible intent, we'll keep things simple for t in self.current_steps: t.add_user_message(messages[0]) else: # this simplifies conversion between formats, but breaks the logic if is_used_for_conversion: for t in self.current_steps: t.add_events(messages) return # If there are multiple different intents the # user can use the express the same thing # we need to copy the blocks and create one # copy for each possible message prefix = GENERATED_CHECKPOINT_PREFIX + "OR_" generated_checkpoint = rasa.shared.core.training_data.structures.generate_id( prefix, GENERATED_HASH_LENGTH ) updated_steps = [] for t in self.current_steps: for m in messages: copied = t.create_copy(use_new_id=True) copied.add_user_message(m) copied.end_checkpoints = [Checkpoint(generated_checkpoint)] updated_steps.append(copied) self.current_steps = updated_steps