def continue_dialogue(self, args=None):
        """
        Perform one dialogue turn

        :param args: input to this agent
        :return: output of this agent
        """

        utterance = None

        if self.INTERACTION_MODE == 'text' and not self.USE_GUI:
            utterance = input('USER > ')
            self.prev_m_out = ConversationalFrame(utterance)

        elif self.INTERACTION_MODE == 'speech' and not self.USE_GUI:
            # Listen for input from the microphone
            with speech_rec.Microphone() as source:
                print('(listening...)')
                audio = self.asr.listen(source, phrase_time_limit=3)

            try:
                # This uses the default key
                utterance = self.asr.recognize_google(audio)
                print("Google ASR: " + utterance)

                self.prev_m_out = ConversationalFrame(utterance)

            except speech_rec.UnknownValueError:
                print("Google ASR did not understand you")

            except speech_rec.RequestError as e:
                print("Google ASR request error: {0}".format(e))

        elif args and 'input' in args:
            self.prev_m_out = ConversationalFrame(args['input'])

        for m in self.ConversationalModules:
            # If executing parallel sub-modules
            if isinstance(m, list):
                idx = 0
                prev_m_out = deepcopy(self.prev_m_out)
                self.prev_m_out.content = {}

                for sm in m:
                    # WARNING! Module compatibility cannot be guaranteed here!
                    sm.generic_receive_input(prev_m_out)
                    sm_out = sm.generic_generate_output(prev_m_out)

                    if not isinstance(sm_out, ConversationalFrame):
                        sm_out = ConversationalFrame(sm_out)

                    self.prev_m_out.content['sm'+str(idx)] = sm_out.content
                    idx += 1

            else:
                # WARNING! Module compatibility cannot be guaranteed here!
                m.generic_receive_input(self.prev_m_out)
                self.prev_m_out = m.generic_generate_output(self.prev_m_out)

                # Make sure prev_m_out is a Conversational Frame
                if not isinstance(self.prev_m_out, ConversationalFrame):
                    self.prev_m_out = ConversationalFrame(self.prev_m_out)

            # DEBUG:
            if isinstance(self.prev_m_out.content, str):
                print(f'(DEBUG) {self.agent_role}> '
                      f'{str(self.prev_m_out.content)}')

        self.dialogue_turn += 1

        # In text or speech based interactions, return the input utterance as
        # it may be used for statistics or to show it to a GUI.
        return {'input_utterance': utterance,
                'output_raw': self.prev_m_out.content,
                'output_dacts': '',
                'goal': self.agent_goal
                }

        Perform one dialogue turn

        :param args: input to this agent
        :return: output of this agent
        
plato/agent/conversational_agent/conversational_generic_agent.py