def end_dialogue(self):
        """
        Perform final dialogue turn. Save models if applicable.

        :return:
        """

        if self.dialogue_episode % self.train_interval == 0:
            for m in self.ConversationalModules:
                if isinstance(m, list):
                    for sm in m:
                        sm.train(self.recorder.dialogues)
                else:
                    m.train(self.recorder.dialogues)

        if self.dialogue_episode % self.SAVE_INTERVAL == 0:
            for m in self.ConversationalModules:
                if isinstance(m, list):
                    for sm in m:
                        sm.save()
                else:
                    m.save()

        # Keep track of dialogue statistics
        self.dialogue_episode += 1

        if self.dialogue_turn > 0:
            self.total_dialogue_turns += self.dialogue_turn

        # Count successful dialogues
        _, _, obj_succ = self.reward_func.calculate(
            self.get_state(),
            [],
            # TODO: In case of single agents, we actually need the user's goal
            goal=self.agent_goal,
            agent_role=self.agent_role)

        self.num_successful_dialogues += 1 if obj_succ else 0

        Perform final dialogue turn. Save models if applicable.

        :return:
        
plato/agent/conversational_agent/conversational_generic_agent.py