diff --git a/clemgame/clemgame.py b/clemgame/clemgame.py index 10b11d72071032024461e694ca3ffb662109130e..bae71bc0baec75f1ba2d0137dec7e7342e8c272a 100644 --- a/clemgame/clemgame.py +++ b/clemgame/clemgame.py @@ -353,7 +353,7 @@ class DialogueGameMaster(GameMaster): """ Add a player to the game. - Note: The players will be called at the same order as added! + Note: The players will be called in the same order as added! :param player: to be added to the game """ @@ -389,29 +389,50 @@ class DialogueGameMaster(GameMaster): for player in self.__player_sequence(): if not self._does_game_proceed(): break # potentially stop in between player turns - # GM -> Player - history = self.messages_by_names[player.descriptor] - assert history, f"messages history must not be empty for {player.descriptor}" + self.prompt(player) + while self._should_reprompt(player): + self._on_before_reprompt(player) + self.prompt(player, is_reprompt = True) + self._on_after_turn(self.current_turn) + self.current_turn += 1 + self._on_after_game() - last_entry = history[-1] - assert last_entry["role"] != "assistant", "Last entry should not be assistant " \ - "b.c. this would be the role of the current player" - message = last_entry["content"] + def prompt(self, player: Player, is_reprompt=False): + # GM -> Player + history = self.messages_by_names[player.descriptor] + assert history, f"messages history must not be empty for {player.descriptor}" - action = {'type': 'send message', 'content': message} - self.log_event(from_='GM', to=player.descriptor, action=action) + last_entry = history[-1] + assert last_entry["role"] != "assistant", "Last entry should not be assistant " \ + "b.c. this would be the role of the current player" + message = last_entry["content"] - _prompt, _response, response_message = player(history, self.current_turn) + action_type = 'send message' if not is_reprompt else 'send message (reprompt)' + action = {'type': action_type, 'content': message} + self.log_event(from_='GM', to=player.descriptor, action=action) - # Player -> GM - action = {'type': 'get message', 'content': response_message} - self.log_event(from_=player.descriptor, to="GM", action=action, call=(_prompt, _response)) + _prompt, _response, response_message = player(history, self.current_turn) - # GM -> GM - self.__validate_parse_and_add_player_response(player, response_message) - self._on_after_turn(self.current_turn) - self.current_turn += 1 - self._on_after_game() + # Player -> GM + action = {'type': 'get message', 'content': response_message} + self.log_event(from_=player.descriptor, to="GM", action=action, call=(_prompt, _response)) + + # GM -> GM + self.__validate_parse_and_add_player_response(player, response_message) + + def _should_reprompt(self, player: Player): + return False + + def _on_before_reprompt(self, player: Player): + """ + Hook + + Change the prompt to reprompt the player on e.g. an invalid response. + Add the new prompt to the players message via self.add_user_message(player, new_prompt) + + :param player: that produced the invalid response + """ + pass def log_message_to(self, player: Player, message: str): """ GM -> Player """ diff --git a/games/taboo/master.py b/games/taboo/master.py index d17163229b0b926c51e69d59a2af01691e2a6ae7..25d5b06ef8378d3983ba677bf6f9c4740a697ce7 100644 --- a/games/taboo/master.py +++ b/games/taboo/master.py @@ -75,12 +75,12 @@ def check_clue(utterance: str, target_word: str, related_words: List[str]) -> Li clue_lemma = EN_LEMMATIZER.lemmatize(clue_word) if clue_lemma == target_lemma: return [{ - "message": f"Target word '{target_word}' is morphological similar to clue word '{clue_word}'", + "message": f"Target word '{target_word}' is morphologically similar to clue word '{clue_word}'", "type": 0 }] if clue_lemma in related_lemmas: return [{ - "message": f"Related word is morphological similar to clue word '{clue_word}'", + "message": f"Related word is morphologically similar to clue word '{clue_word}'", "type": 1 }] return errors