def query_api_transitions(self, url, slot, value): result = self.api.query(slot, value) if result == value: self.task_schema.data[slot]["value"] = value self.task_schema.data[slot]["to_confirm"] = False self.curr_state = "ASK PREFERENCE" elif isinstance(result, DialogueAct): self.task_schema.data[result.slot] = { "value": None, "to_confirm": True, "to_agenda": False, "url": "" } self.task_schema.data[slot]["value"] = value self.task_schema.data[slot]["to_confirm"] = False self.curr_state = "ASK PREFERENCE" return [result] elif result is not None: self.curr_state = "ASK PREFERENCE" self.data_to_confirm = True return [DialogueAct("confirm", slot, result)] else: self.curr_state = "ASK PREFERENCE" return [DialogueAct("negate"), DialogueAct("request", slot)]
def build_agenda(scenario): agenda = Agenda() # add bye act at the end of the agenda agenda.add_dialogue_act(DialogueAct('bye')) # add request act agenda.add_dialogue_act(DialogueAct('request', 'Registration')) for user_goal in scenario.user_goals: if user_goal.to_agenda: agenda.add_dialogue_act( DialogueAct('inform', user_goal.slot, user_goal.value)) return agenda
def request_handler(self, dialogue_act): value = None for goal in self.user_goals: if goal.slot == dialogue_act.slot: value = goal.value self.agenda.add_dialogue_act( DialogueAct("inform", dialogue_act.slot, value))
def ask_preference_transitions(self, user_action): if self.data_to_confirm is True: self.task_schema.data["Area"]["value"] = "Some value" self.task_schema.data["Area"]["to_confirm"] = False result = [] for da in user_action.dialogue_acts: # scan all dialogue acts if da.act == "inform": if self.task_schema.data[da.slot][ "to_confirm"]: # if value needs to be validated self.curr_state = "QUERY API" res = self.handlers[self.curr_state]( self.task_schema.data[da.slot]["url"], da.slot, da.value) if res: result.append(res) else: self.task_schema.data[da.slot]["value"] = da.value # HAS SLOT UNFULFILLED """ id result is empty and there are slots unfulfilled""" if not result and self.task_schema.has_slots_unfulfilled( ): # stay in same state return system action result.append( [DialogueAct("request", self.task_schema.get_missing_slot())]) # ALL SLOT FILLED elif self.task_schema.is_completed(): self.curr_state = "EXECUTE REGISTRATION" result.append(self.handlers[self.curr_state]()) return SystemAction([item for sublist in result for item in sublist])
def validate_phone(phone): z = phonenumbers.parse(phone, "FI") if phonenumbers.is_valid_number(z): return DialogueAct("request", "Pincode") else: return None
def confirm_handler(self, dialogue_act): for ug in self.user_goals: if ug.slot == dialogue_act.slot and ug.value == dialogue_act.value: return self.agenda.add_dialogue_act(DialogueAct("affirm")) return self.agenda.add_dialogue_act(DialogueAct("negate"))
def main(): """Connect to MongoDB""" db_connector = DatabaseConnector() """Task specification - slot definition Define all entities that characterize the considered task""" phone = PhoneSlot() area = AreaSlot() pincode = PincodeSlot() plate = LicensePlateSlot() terms = TermsSlot() task_slots = [phone, area, pincode, plate, terms] """Main loop, generates N dialogues""" for _ in range(n_dialog): lines = [ da for da in random.choice([START_DIALOGUE1, START_DIALOGUE2]) ] # select random custom dialogue start """Build scenario from task schema""" bot_registration_task = TaskSchema(task_slots) scenario_generator = ScenarioGenerator(bot_registration_task) scenario = scenario_generator.generate_scenario() """Build user simulator using scenario""" user_simulator = AgendaBasedSimulator(scenario) """User simulator handlers definition Defines how the user simulator should handle dialogue acts coming from the system simulator""" def default_handler(self, dialogue_act): return def negate_handler(self, dialogue_act): self.end_dialogue = True return def request_handler(self, dialogue_act): value = None for goal in self.user_goals: if goal.slot == dialogue_act.slot: value = goal.value self.agenda.add_dialogue_act( DialogueAct("inform", dialogue_act.slot, value)) def confirm_handler(self, dialogue_act): for ug in self.user_goals: if ug.slot == dialogue_act.slot and ug.value == dialogue_act.value: return self.agenda.add_dialogue_act(DialogueAct("affirm")) return self.agenda.add_dialogue_act(DialogueAct("negate")) def inform_handler(self, dialogue_act): da = self.agenda.get_dialogue_act(dialogue_act.slot) da.value = True self.agenda.remove_dialogue_act(da) user_simulator.add_handler(request_handler, "request") user_simulator.add_handler(default_handler, "affirm") user_simulator.add_handler(negate_handler, "negate") user_simulator.add_handler(default_handler, "notify success") user_simulator.add_handler(inform_handler, "inform") user_simulator.add_handler(confirm_handler, "confirm") """Build system simulator using the task schema""" system_simulator = FSMSystemSimulator(bot_registration_task) print(user_simulator.agenda.to_formatted_string() ) # print initial agenda print("=" * 20) user_state = user_simulator.agenda """Build dialogue until ending conditions are met""" while len( user_state.dialogue_acts ) > 0 and system_simulator.curr_state != "END" and not user_simulator.end_dialogue: na, ua = user_simulator.select_action() # select user action ua = user_simulator.introduce_misspell( ua) # potentially introduce syntactic error into user acts print("==> User: "******"User", 'da': [da.to_json_format() for da in ua.dialogue_acts] }) sa = system_simulator.get_system_action(ua) # select system action print("==> System: ", [da.to_formatted_string() for da in sa.dialogue_acts]) lines.append({ 'sender': "Chatbot", 'da': [da.to_json_format() for da in sa.dialogue_acts] }) user_simulator.get_next_state(sa) # update agenda if not user_simulator.end_dialogue: na, ua = user_simulator.select_action() print("==> User: "******"User", 'da': [ua.dialogue_acts[-1].to_json_format()] }) if user_simulator.end_dialogue: # user interrupts conversation print("==> User: ['inform(Registration=interrupted)]") lines.append({ 'sender': "User", 'da': [ DialogueAct('inform', 'registration', 'interrupted').to_json_format() ] }) print("Dialogue finished") """Save generated dialogue on db""" db_connector.create_dialog(lines) print("=" * 20)
def notify_failure_transitions(self): self.curr_state = "END" return [ DialogueAct("notify failure"), DialogueAct("inform", "Registration", "False") ]
def notify_success_transitions(self): self.curr_state = "END" return [ DialogueAct("notify success"), DialogueAct("inform", "Registration", "True") ]