dialogue_state = { # current context should be set to an act that is currently taking place 'current_context' : None, # topics will be an array of dicts structured similar to this # {'act': 'notifications', 'slots': [('time_when', None), ('liczba', ''), ('timeunit', None)]} 'topics': [], # facts is a dict of contextual data such as selected repo and a timeframe 'facts': { 'repo' : None, 'time': None }, 'counter': 0 } def monitor_stanu_dialogowego(frame): not_pivot_acts = ['time', 'repo', 'howmany'] global dialogue_state # Some frames can reset the dialogue state, like saying hello. incr_counter(dialogue_state) # Discarding acts that were not identified properly, but lets keep increasing the counter if frame['act'] == 'null': return dialogue_state reset_state_if_needed(frame, dialogue_state) if frame['act'] not in not_pivot_acts: dialogue_state['current_context'] = frame['act'] append_or_merge_frame(frame, dialogue_state) return dialogue_state def append_or_merge_frame(frame, dialogue_state): act = frame['act'] act_from_state = list(filter(lambda x: x['act'] == act, dialogue_state['topics'])) if len(act_from_state) > 0: append_or_merge_slots(frame['slots'], act_from_state[0]['slots']) else: dialogue_state['topics'].append(frame) def update_facts_if_needed(slot): global dialogue_state if slot != None and len(slot) > 1: if slot[1] is None or slot[1] == '': return if slot[0] == 'repo': dialogue_state['facts']['repo'] = slot[1] elif slot[0] == 'time': dialogue_state['facts']['time'] = slot[1] def append_or_merge_slots(frame_slots, state_slots): """ This function expects both parameters to be an array of tuples (slot_name, slot_value), and will merge frame slots into state_slots (on unique slot names). """ for frame_slot in frame_slots: merged = False for i in range(len(state_slots)): if len(frame_slot) > i: update_facts_if_needed(frame_slot[i]) if state_slots[i][0] == frame_slot[0]: merged = True # Do not merge empty incomming slots if frame_slot[1] is not None and not len(frame_slot[1]) == 0: state_slots[i] = frame_slot break if not merged: state_slots.append(frame_slot) def incr_counter(dialogue_state): current_val = dialogue_state['counter'] dialogue_state['counter'] = current_val + 1 def reset_state_if_needed(frame, dialogue_state): if frame['act'] == "hello" or frame['act'] == "bye": dialogue_state['topics'] = [] dialogue_state['counter'] = 0 # should we reset 'facts' aswell?