in mm_action_prediction/tools/extract_actions.py [0:0]
def gen_getinfo_from_annotation(round_datum, reversed_dialog_coref_map):
""" Generate GET_INFO_ACTIONs inferred based on NLU/NGL annotation.
Args:
round_datum: user-assistant turn-pair, including annotation
reversed_dialog_coref_map: maps per dialog object ids to furniture ids
Returns:
list of inferred GET_INFO_ACTIONs for this turn.
"""
da_ask_regex = re.compile("DA:ASK:GET:([^.]+)[.](.+)")
da_inform_regex = re.compile("DA:INFORM:GET:([^.]+)[.](.+)")
user_action_refs = data_support.get_object_references(
round_datum['turn_label'],
reversed_dialog_coref_map
)
system_action_refs = data_support.get_object_references(
round_datum['system_turn_label'],
reversed_dialog_coref_map
)
# For GetInfo, look for DA:ASK:GET intent with attributes and extract
# the attributes, and check system responded
get_info_attributes = []
for intent, obj_refs in user_action_refs.items():
da_ask_match = da_ask_regex.match(intent)
if da_ask_match:
obj = da_ask_match[1]
attribute = da_ask_match[2]
furniture_id = [r[1] for r in obj_refs]
# if object reference(s) missing try to find references in the
# assistant action
if not furniture_id:
last_resort_id = None
for sys_intent, sys_obj_refs in system_action_refs.items():
if sys_obj_refs:
da_inform_match = da_inform_regex.match(sys_intent)
# if any object id found in any DA:INFORM:GET, keep the
# first one found as a last resort fall-back
if not last_resort_id:
last_resort_id = [r[1] for r in sys_obj_refs]
if da_inform_match:
# try strict match first; match object and attribute
if (
da_inform_match[1] == obj
and da_inform_match[2] == attribute
):
furniture_id = [r[1] for r in sys_obj_refs]
break # take the first strict match found.
# else object matches and system attribute is a
# super set of the attribute asked, i.e. 'info'
elif (
da_inform_match[1] == obj
and da_inform_match[2] == 'info'
):
furniture_id = [r[1] for r in sys_obj_refs]
# keep looping in case a strict match exists.
# if nothing better so far, accept object mis-match
# (allows for annotation error)
elif (
not furniture_id
and (
da_inform_match[2] == attribute
or da_inform_match[2] == 'info'
)
):
furniture_id = [r[1] for r in sys_obj_refs]
# keep looping in case something better
# if nothing better found
if not furniture_id and last_resort_id:
furniture_id = last_resort_id
get_info_attributes.append((attribute, furniture_id))
# Check the system responded; at least one DA:INFORM:GET intent with an
# attribute
system_responded = any(
da_inform_regex.match(intent) for intent in system_action_refs.keys()
)
get_info_actions = []
if get_info_attributes and system_responded:
for attribute, furniture_ids in get_info_attributes:
if attribute not in FILTER_MATCHES:
attribute = "info"
new_action = {
API: GET_INFO_ACTION,
ARGS: {
MATCHES: attribute,
FURNITURE_ID: furniture_ids
},
}
get_info_actions.append(new_action)
return get_info_actions