import copy from modules.nlu import Act import json class DialogStateMonitor: def __init__(self): self.__initial_state = dict( belief_state={ 'item': {}, 'address': {}, 'card_nr': {}, 'delivery_method': {}, 'payment_method': {}, 'email': {}, 'order-completed': False, }, act='', slot_names=[]) self.state = copy.deepcopy(self.__initial_state) def is_value_empty(self, d, key): value = d.get(key, None) if value in [None, '', [], {}]: return True return False def update_act(self, intent): self.state['act'] = intent def update_slot_names(self, slots_names): self.state['slot_names'] = slots_names def check_order_complete(self): all_filled = all(bool(self.state['belief_state'][key]) for key in ['item', 'address', 'card_nr', 'delivery_method', 'payment_method', 'email']) self.state['belief_state']['order-complete'] = all_filled def find_first_empty_slot(self): for slot_name, slot_value in self.state['belief_state'].items(): if slot_name != 'order-completed' and slot_value in [None, '', [], {}]: return slot_name def update(self, act: Act) -> None: if act.intent == 'inform': self.update_act(act.intent) slots_mapping = { 'item': [], 'address': [], 'card_nr': [], 'delivery_method': [], 'payment_method': [], 'email': [] } for slot in act.slots: if slot.name in slots_mapping and self.is_value_empty(self.state['belief_state'], slot.name): slots_mapping[slot.name].append(slot.value) # To do: normalization for slot_name, values in slots_mapping.items(): if values: self.state['belief_state'][slot_name] = values elif act.intent == 'request': self.update_act(act.intent) slots_names = [slot.name for slot in act.slots] self.update_slot_names(slots_names) elif act.intent == 'bye': self.update_act(act.intent) elif act.intent == 'unknown': self.update_act(act.intent) self.check_order_complete()