94 lines
2.9 KiB
Python
94 lines
2.9 KiB
Python
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 add_fact(key, value):
|
|
global dialogue_state
|
|
dialogue_state['facts'][key] = value
|
|
|
|
|
|
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?
|