示例#1
0
    def get_action(self, state: State, action_space: List[Action],
                   additional_features: AdditionalFeatures) -> Action:
        """On a high level, this policy first disagree with the user softly, then switch
        to a different entity and completely agree with the user.

        :param state: [description]
        :type state: State
        :param action_space: [description]
        :type action_space: List[Action]
        :param additional_features: [description]
        :type additional_features: AdditionalFeatures
        :return: [description]
        :rtype: Action
        """
        action = Action(exit=True)
        if len(state.action_history) == 0:
            user_sentiment_history = dict(state.user_sentiment_history)
            if state.cur_phrase not in user_sentiment_history:
                return Action(solicit_opinion=True)
            else:
                return Action(solicit_reason=True)
        prev_action = state.action_history[-1]
        if prev_action.solicit_opinion or prev_action.suggest_alternative:
            if state.cur_sentiment == 2:
                action = Action(exit=True)
            elif additional_features.detected_user_gave_reason:
                action = self.agree_reason_agree(state, action_space)
            else:
                action = Action(solicit_reason=True)
        elif prev_action.solicit_reason:
            if not additional_features.detected_user_disinterest:
                action = self.agree_reason_agree(state, action_space)
        return action
示例#2
0
 def agree_reason_agree(self, state: State, action_space: List[Action]):
     action = Action(sentiment=state.cur_sentiment,
                     give_agree=True,
                     give_reason=True,
                     solicit_agree=True)
     if action not in action_space:
         action = Action(exit=True)
     return action
 def get_agree_suggest_alternative(self, state: State,
                                   action_space: List[Action]):
     action = Action(suggest_alternative=True)
     if action not in action_space:
         action = Action(suggest_alternative=True)
     if action not in action_space:
         action = Action(exit=True)
     return action
示例#4
0
 def agree_suggest_alternative(self, state: State,
                               action_space: List[Action]):
     action = Action(sentiment=4 - state.cur_sentiment,
                     suggest_alternative=True)
     if action not in action_space:
         action = Action(suggest_alternative=True)
     if action not in action_space:
         action = Action(exit=True)
     return action
示例#5
0
 def disagree_solicit_agree(self, state: State, action_space: List[Action]):
     action = Action(sentiment=4 - state.cur_sentiment,
                     give_reason=True,
                     solicit_agree=True)
     if action not in action_space:
         action = Action(sentiment=4 - state.cur_sentiment,
                         suggest_alternative=True)
     if action not in action_space:
         action = Action(exit=True)
     return action
    def get_prompt(self, state: State) -> PromptResult:
        """This method is the same as get_response. Only difference is that 

        1. we do not get a list of reasons (because there is not enough time)
        2. we only chose to solicit an opinion if user didn't have an opinion on it before, or 
        3. we will solicit a reason if user told us before that they like or dislike a phrase
        
        :param state: the current state
        :type state: State
        :return: a result chirpy can use
        :rtype: PromptResult
        """
        self.initialize_turn()
        if state.last_turn_prompt:
            return emptyPrompt(state)
        phrase, priority, transition_phrase = self.select_phrase_for_prompt(state)
        if phrase is None:
            return emptyPrompt(state)
        utterance = self.state_manager.current_state.text
        additional_features = self.populate_features(state, utterance)
        additional_features.detected_phrases = tuple([phrase for phrase in additional_features.detected_phrases if phrase not in state.phrases_done])

        # Then need to advance the state using the utterance
        state_p = state_actions.next_state(state, utterance, additional_features)
        if state_p is None:
            # Special handling for prompt: Add phrase and sentiment
            state_p = state.reset_state()
            state_p.cur_phrase = phrase
            user_sentiments_history = dict(state_p.user_sentiment_history)
            state_p.cur_sentiment = user_sentiments_history[phrase] if phrase in user_sentiments_history else 2
        if state_p.cur_sentiment != 2:
            action = Action(solicit_reason=True)
        else:
            action = Action(solicit_opinion=True)
        # Then need to utterancify the action
        text, phrase, reason = fancy_utterancify_prompt(state_p, action, [], [], [], state_p.cur_phrase not in state.detected_opinionated_phrases, 
                                                        self.state_manager.current_state.choose_least_repetitive) # type: ignore
        # Then need to fill the rest of the fields of state_p (through mutation)
        state_p = state_actions.fill_state_on_action(state_p, action, text, phrase, additional_features, reason, 
            self.opinionable_phrases, self.opinionable_entities)

        state_p.last_turn_prompt, state_p.last_turn_select = True, False
        wiki_entity = None
        if self.opinionable_phrases[phrase].good_for_wiki:
            wiki_entity = get_entity_by_wiki_name(self.opinionable_phrases[phrase].wiki_entity_name)
        state.last_turn_prompt, state.last_turn_select = False, False

        text = ' '.join((transition_phrase, text))
            
        return PromptResult(text, priority, state, wiki_entity, conditional_state=state_p)
示例#7
0
    def get_action(self, state: State, action_space: List[Action],
                   additional_features: AdditionalFeatures) -> Action:
        """On a high level, this policy first disagree with the user softly, then switch
        to a different entity and completely agree with the user.

        :param state: [description]
        :type state: State
        :param action_space: [description]
        :type action_space: List[Action]
        :param additional_features: [description]
        :type additional_features: AdditionalFeatures
        :return: [description]
        :rtype: Action
        """
        number_of_switches = len([
            action for action in state.action_history
            if action.suggest_alternative
        ])
        action = Action(exit=True)
        if len(state.action_history) == 0:
            user_sentiment_history = dict(state.user_sentiment_history)
            if state.cur_phrase not in user_sentiment_history:
                return Action(solicit_opinion=True)
            else:
                return Action(solicit_reason=True)
        prev_action = state.action_history[-1]
        if additional_features.detected_user_sentiment_switch and not prev_action.solicit_disambiguate:
            action = Action(exit=True)
        elif prev_action.solicit_disambiguate and additional_features.detected_no and state.cur_sentiment == 2:
            action = Action(exit=True)
        elif prev_action.solicit_opinion or prev_action.suggest_alternative \
                or prev_action.solicit_disambiguate:
            if state.cur_sentiment == 2:
                action = Action(exit=True)
            elif number_of_switches == 0:
                if additional_features.detected_user_gave_reason:
                    action = self.disagree_reason_agree(state, action_space)
                else:
                    action = Action(solicit_reason=True)
            else:
                if additional_features.detected_user_gave_reason:
                    action = self.agree_reason_agree(state, action_space)
                else:
                    action = self.agree_reason_reason(state, action_space)
        elif prev_action.solicit_reason:
            if number_of_switches == 0 and not additional_features.detected_user_disinterest:
                action = self.disagree_reason_agree(state, action_space)
            elif number_of_switches > 0 and not additional_features.detected_user_disinterest:
                action = self.agree_reason_agree(state, action_space)
        elif prev_action.solicit_agree:
            if number_of_switches == 0:  # Check if user is still interested
                action = Action(suggest_alternative=True)
                if action not in action_space:
                    action = Action(exit=True)
        return action
示例#8
0
    def get_action(self, state: State, action_space: List[Action],
                   additional_features: AdditionalFeatures) -> Action:
        """On a high level, this policy follows the following fixed trajectory

        1. Ask the user if they like the phrase or not (skip if we already have that info)
        2. Agree with the user, give a reason (if possible) and ask user's reason
        3. Give another reason (if possible) and ask if user agrees
        4. Switch to a different entity (if possible), and start over at stage 1
        
        :param state: the current state
        :type state: State
        :param action_space: a list of available actions
        :type action_space: List[Action]
        :param additional_features: additional features the policy can use
        :type additional_features: AdditionalFeatures
        :return: a specific action within the confines of the action spaces
        :rtype: Action
        """
        number_of_switches = len([
            action for action in state.action_history
            if action.suggest_alternative
        ])
        action = Action(exit=True)
        if len(state.action_history) == 0:  # First turn
            user_sentiment_history = dict(state.user_sentiment_history)
            if state.cur_phrase not in user_sentiment_history:
                action = Action(solicit_opinion=True)
            else:
                action = Action(sentiment=4 - state.cur_sentiment,
                                give_agree=True,
                                solicit_reason=True)
                state.cur_sentiment = user_sentiment_history[state.cur_phrase]
        elif additional_features.detected_user_sentiment_switch and not state.action_history[
                -1].solicit_disambiguate:
            action = Action(exit=True)
        elif state.action_history[
                -1].solicit_disambiguate and additional_features.detected_no and state.cur_sentiment == 2:
            action = Action(exit=True)
        elif state.action_history[-1].solicit_opinion or state.action_history[-1].suggest_alternative \
                or state.action_history[-1].solicit_disambiguate:
            if state.cur_sentiment == 2:
                action = Action(exit=True)
            elif number_of_switches == 0:
                if additional_features.detected_user_gave_reason:
                    action = self.agree_solicit_agree(state, action_space)
                else:
                    action = self.disagree_solicit_reason(state, action_space)
            else:
                if additional_features.detected_user_gave_reason:
                    action = self.agree_solicit_agree(state, action_space)
                else:
                    action = self.agree_reason_reason(state, action_space)
        elif state.action_history[-1].solicit_reason:
            if not additional_features.detected_user_disinterest:  # Check if user is still interested
                action = self.agree_solicit_agree(state, action_space)
        elif state.action_history[-1].solicit_agree:
            if number_of_switches == 0:  # Check if user is still interested
                action = self.agree_suggest_alternative(state, action_space)
        return action
示例#9
0
    def get_action(self, state: State, action_space: List[Action],
                   additional_features: AdditionalFeatures) -> Action:
        """On a high level, this policy follows the following fixed trajectory

        1. Ask the user if they like the phrase or not (skip if we already have that info)
        2. Agree with the user, give a reason (if possible) and ask user's reason
        3. Give another reason (if possible) and ask if user agrees
        4. Switch to a different entity (if possible), and start over at stage 1
        
        :param state: the current state
        :type state: State
        :param action_space: a list of available actions
        :type action_space: List[Action]
        :param additional_features: additional features the policy can use
        :type additional_features: AdditionalFeatures
        :return: a specific action within the confines of the action spaces
        :rtype: Action
        """
        action = Action(exit=True)
        if len(state.action_history) == 0:  # First turn
            user_sentiment_history = dict(state.user_sentiment_history)
            if state.cur_phrase not in user_sentiment_history:
                action = Action(solicit_opinion=True)
            else:
                action = self.get_agree_solicit_reason(state, action_space)
        elif state.action_history[-1].solicit_opinion:
            if state.cur_sentiment == 2:
                action = Action(exit=True)
            elif additional_features.detected_user_gave_reason:
                action = self.get_agree_solicit_agree(state, action_space)
            else:
                action = self.get_agree_solicit_reason(state, action_space)
        elif state.action_history[-1].solicit_reason:
            if len(state.action_history
                   ) == 1:  # Solicit reason on the previous turn
                action = self.get_agree_solicit_agree(state, action_space)
        return action
示例#10
0
from chirpy.response_generators.opinion2.state_actions import Action

ACTION_SPACE = [Action(solicit_opinion=True), \
    Action(exit=True), Action(solicit_reason=True), Action(suggest_alternative=True)]
for sentiment in [0, 4]:
    for give_agree in [True, False]:
        for give_reason in [True, False]:
            if not give_agree and not give_reason:
                continue
            for solicit_agree, solicit_reason, suggest_alternative in [(True, False, False), (False, True, False), (False, False, True)]:
                ACTION_SPACE += [Action(sentiment, give_agree, give_reason, False, False, solicit_agree, solicit_reason, suggest_alternative)]
ACTION_SPACE = [action for action in ACTION_SPACE if not (not action.give_reason and action.solicit_agree)]