def _respond_confirm(self, agent_action: DialogAction) -> 'DialogAction': """ Method resolves the confirm dialog act, where the agent is asking the user to validate their preferences. Compare the prefence key/values sent in the params of the dialog action to usersim's own prefs in the goal obj. Return a affirm or negate dialog action. """ confirm_params = list(agent_action.params.items()) inform_slots = self.goal.get_inform_slots() # Check if agent is asking to confirm single or multiple prefs if len(confirm_params) == 1: # Single pref case if confirm_params[0][0] not in inform_slots: return self._respond_general( DialogAction(dialog_act="inform", params={"unknown": None})) elif inform_slots[confirm_params[0][0]] == confirm_params[0][1]: utterance = self.get_utterance( DialogAction(dialog_act="affirm")) return DialogAction(dialog_act="affirm", nl_utterance=utterance) else: utterance = self.get_utterance( DialogAction(dialog_act="negate")) return DialogAction(dialog_act="negate", nl_utterance=utterance) # Multiple prefs confirm case else: self._respond_confirm_multiple(agent_action)
def _request_user_pref(self): # Find first unfilled slot and ask user about it for k,v in self.goal.request_slots.items(): if v == "UNK": action = DialogAction(dialog_act="request", params={k: None}) action.update_utterance(self.get_utterance(action)) return action # If agent knows all of user's preferences, make a suggestion return self._make_recommendation()
def _respond_request(self, agent_action: DialogAction) -> 'DialogAction': """ Respond to an agent's request for more information by informing them based on user preferences. """ params = {} inform_slots = self.goal.get_inform_slots() # Loop over user's prefs in inform slots and update return action params for key in agent_action.params: if key in inform_slots: params[key] = inform_slots[key] else: params["no_pref"] = "UNK" ret_action = DialogAction(dialog_act="inform", params=params) ret_action.update_utterance( self.get_utterance(ret_action)) # generate nl utterance return ret_action
def _respond_random_inform(self) -> DialogAction: """ User is speaking first. Will randomly choose its prefrences and inform the agent. """ inform_slots = self.goal.get_inform_slots() # Choose random inform preference rand_param = random.choice(list(inform_slots.keys())) params = dict() params[rand_param] = inform_slots[rand_param] # Generate action action = DialogAction(dialog_act="inform", params=params) action.update_utterance(self.get_utterance(action)) return action
def next(self, agent_action: 'DialogAction', current_turn: int) -> 'DialogAction': """ The next function produces the user simulators next response to the dialog agent. It takes in a dialog action representing the agent's last utterance and current turn. Next use the response router to appropiate select and generate the next response. """ self.current_turn = current_turn if agent_action is None and self.dialog_status == DialogStatus.NOT_STARTED: self.dialog_status = DialogStatus.NO_OUTCOME_YET return self._respond_general(DialogAction(dialog_act="greetings")) elif self.current_turn == 1 and agent_action.dialog_act == "greetings": self.dialog_status = DialogStatus.NO_OUTCOME_YET return self._respond_random_inform() elif self.dialog_status == DialogStatus.FINISHED: return self._respond_general(DialogAction(dialog_act="bye")) else: return self.response_router[agent_action.dialog_act](agent_action)
def _make_recommendation(self) -> DialogAction: params = self.goal.request_slots suggestions = self.domain.domain_kb.get_suggestions(params, 1) if len(suggestions) == 0: action = DialogAction(dialog_act="inform", params={"name": 'aladin', 'phone': '933-333-2222', 'address':'324343'}) action.update_utterance(self.get_utterance(action)) else: suggestion = suggestions[0][0] recommend_params = {"name", "phone", "address"} params = dict() for rp in recommend_params: params.update({rp:suggestion.get(rp)}) action = DialogAction(dialog_act="inform", params=params) action.update_utterance(self.get_utterance(action)) return action
def _respond_confirm_multiple( self, agent_action: 'DialogAction') -> 'DialogAction': """ Placeholder for handling multipele request from agent. User responds they don't know. """ return DialogAction(dialog_act="inform", params={"unknown": None})
def _respond_to_suggestion(self, agent_action: DialogAction) -> 'DialogAction': """ Respond to agent's suggestion and update user's goal to reflect new suggestion information. If agent has provided partial information, usersim will ask for more information based on the request slots in its goal object that are set to "UNK". """ ret_action = DialogAction() # 1. Update goal with system suggestion and update dialog state self.goal.update_goal(agent_action.params) # Update dialog state base on new information self._update_dialog_status() # 2. Check dialog state. If not finished request follow-up. if self.dialog_status == DialogStatus.FINISHED: # Case: Dialog is finished ret_action.update_dialog_act("bye") ret_action.update_utterance(self.get_utterance(ret_action)) return ret_action else: # Find first UNK slot and request more info. for k, v in self.goal.get_request_slots().items(): if v == "UNK": ret_action.update_dialog_act("request") ret_action.update_params({k: None}) ret_action.update_utterance(self.get_utterance(ret_action)) return ret_action
def next(self, user_action: DialogAction, current_turn: int) -> 'DialogAction': self.current_turn = current_turn if user_action is None and self.dialog_status == DialogStatus.NOT_STARTED: self.dialog_status = DialogStatus.NO_OUTCOME_YET action = DialogAction(dialog_act="greetings") action.update_utterance(self.get_utterance(action)) return action elif user_action.dialog_act == "request": self.dialog_status = DialogStatus.NO_OUTCOME_YET params = {} for k,v in user_action.params.items(): if k in self.dialog_state["inform_slots"]: params[k] = v action = DialogAction(dialog_act="inform", params=params) action.update_utterance(self.get_utterance(action)) return action elif user_action.dialog_act == "bye": self.dialog_status = DialogStatus.FINISHED action = DialogAction(dialog_act="bye") action.update_utterance(self.get_utterance(action)) return action else: if user_action.params is None: return self._request_user_pref() else: self.goal.update_goal(user_action.params) return self._request_user_pref()