def next_action(self, state):
        """
        Consult the dialogue policy and produce the agent's response

        :param state: the current dialogue state
        :return: a list of actions, representing the agent's response
        """
        sys_acts = []

        state_enc = self.encode_state(state)

        if state not in self.policy:
            # TODO: Reactive dialogue policy. Fix this properly.
            state_enc = ''
            if state.user_acts:
                for sa in state.user_acts:
                    state_enc = sa.intent

                    # This is due to the DM rules and to be fair to the other
                    # policies
                    if sa.intent == 'offer':
                        state_enc += '_name'

                    elif sa.params:
                        state_enc += '_' + sa.params[0].slot

                    state_enc += ';'

                state_enc = state_enc[:-1]

        if state_enc in self.policy:
            sys_actions = list(self.policy[state_enc]['dacts'].keys())
            probs = [self.policy[state_enc]['dacts'][i] for i in sys_actions]

            sys_act_slots = \
                deepcopy(random.choices(
                    sys_actions, weights=probs)[0]).split(';')

            for sys_act_slot in sys_act_slots:
                if not sys_act_slot:
                    # Skip empty sys_act_slot strings (e.g. case where
                    # there is ; at the end: inform_food;inform_area;)
                    continue

                sys_act = DialogueAct('UNK')
                sys_act_slot_parts = sys_act_slot.split('_')

                sys_act.intent = sys_act_slot_parts[0]

                if len(sys_act_slot_parts) > 1:
                    sys_act.params = \
                        [DialogueActItem(
                            sys_act_slot_parts[1],
                            Operator.EQ, '')]

                if sys_act.intent == 'offer':
                    sys_act.params = []

                elif sys_act.intent == 'canthelp.exception':
                    sys_act.intent = 'canthelp'

                sys_acts.append(sys_act)

        else:
            print(f'Warning! {self.agent_role} Calculated dialogue policy: '
                  f'state not found, selecting random action.')
            sys_act = DialogueAct('UNK')

            if self.agent_role == 'system':
                sys_act.intent = \
                    random.choice(['welcomemsg', 'inform', 'request'])
            elif self.agent_role == 'user':
                sys_act.intent = random.choice(['hello', 'inform', 'request'])
            else:
                sys_act.intent = random.choice(['bye', 'inform', 'request'])

            sys_acts.append(sys_act)

        return sys_acts

        Consult the dialogue policy and produce the agent's response

        :param state: the current dialogue state
        :return: a list of actions, representing the agent's response
        
plato/agent/component/dialogue_policy/calculated_policy.py