Beispiel #1
0
def suggest_cook_response(vars):
    user_utt = state_utils.get_last_human_utterance(vars)
    try:
        linkto_food_skill_agreed = any(
            [req.lower() in state_utils.get_last_bot_utterance(vars)["text"].lower() for req in TRIGGER_PHRASES]
        )
        if linkto_food_skill_agreed:
            if is_yes(user_utt) or bool(re.search(LIKE_RE, user_utt["text"].lower())):
                state_utils.set_confidence(vars, confidence=CONF_HIGH)
                state_utils.set_can_continue(vars, continue_flag=MUST_CONTINUE)
            elif not is_no(user_utt):
                state_utils.set_confidence(vars, confidence=CONF_MIDDLE)
                state_utils.set_can_continue(vars, continue_flag=CAN_CONTINUE_SCENARIO)
            elif is_no(user_utt):
                state_utils.set_confidence(vars, confidence=CONF_HIGH)
                state_utils.set_can_continue(vars, continue_flag=CAN_NOT_CONTINUE)
                return ACKNOWLEDGEMENTS["fav_food_cook"]
            else:
                state_utils.set_can_continue(vars, continue_flag=CAN_NOT_CONTINUE)
                return error_response(vars)
            return "May I recommend you a meal to try to practice cooking?"
        else:
            state_utils.set_can_continue(vars, continue_flag=CAN_NOT_CONTINUE)
            return error_response(vars)
    except Exception as exc:
        logger.exception(exc)
        sentry_sdk.capture_exception(exc)
        return error_response(vars)
Beispiel #2
0
def switch_to_particular_game_discussion(vars):
    user_uttr = state_utils.get_last_human_utterance(vars)
    user_text = user_uttr.get("text", "").lower()
    prev_bot_uttr = state_utils.get_last_bot_utterance(vars)
    prev_bot_text = prev_bot_uttr.get("text", "")
    found_video_game_in_user_uttr = find_games_in_text(user_text)
    logger.info(
        f"(switch_to_particular_game_discussion)found_video_game_in_user_uttr: {found_video_game_in_user_uttr}"
    )
    found_video_game_in_user_uttr = bool(found_video_game_in_user_uttr)
    found_video_game_in_bot_uttr = find_games_in_text(prev_bot_text)
    logger.info(
        f"(switch_to_particular_game_discussion)found_video_game_in_bot_uttr: {found_video_game_in_bot_uttr}"
    )
    found_video_game_in_bot_uttr = bool(found_video_game_in_bot_uttr)
    choose_particular_game = if_choose_topic(
        user_uttr, prev_bot_uttr) and found_video_game_in_user_uttr
    question_answer_contains_video_game = ("?" not in user_text
                                           and "?" in prev_bot_text
                                           and found_video_game_in_user_uttr)
    bot_asked_about_game_and_user_answered_yes = (found_video_game_in_bot_uttr
                                                  and "?" in prev_bot_text
                                                  and is_yes(user_uttr))
    flag = (lets_talk_about(
        vars, GAMES_WITH_AT_LEAST_1M_COPIES_SOLD_COMPILED_PATTERN)
            or choose_particular_game or question_answer_contains_video_game
            or bot_asked_about_game_and_user_answered_yes)
    logger.info(f"switch_to_particular_game_discussion={flag}")
    return flag
Beispiel #3
0
def wikihow_step_request(ngrams, vars):
    flag = False
    user_uttr = state_utils.get_last_human_utterance(vars)
    isyes = is_yes(state_utils.get_last_human_utterance(vars))
    shared_memory = state_utils.get_shared_memory(vars)
    wikihow_article = shared_memory.get("wikihow_article", "")
    prev_wikihow_title = shared_memory.get("prev_wikihow_title", "")
    used_wikihow_titles = set(shared_memory.get("used_wikihow_titles", []))
    logger.info(
        f"wikihow_step_request, prev_wikihow_title {prev_wikihow_title} used_wikihow_titles "
        f"{used_wikihow_titles}")
    found_title = ""
    if wikihow_article:
        article_content = get_wikihow_content(wikihow_article)
        if article_content:
            all_page_titles = article_content.keys()
            for title in all_page_titles:
                if title not in used_wikihow_titles:
                    found_title = title
                    break
    further = re.findall(r"(more|further|continue|follow)", user_uttr["text"],
                         re.IGNORECASE)
    if found_title or prev_wikihow_title:
        flag = True
    if prev_wikihow_title and not (isyes or further):
        flag = False
    logger.info(f"wikihow_step_request={flag}")
    return flag
Beispiel #4
0
def what_cuisine_response(vars):
    user_utt = state_utils.get_last_human_utterance(vars)
    bot_utt = state_utils.get_last_bot_utterance(vars)["text"].lower()
    banned_words = ["water"]
    linkto_food_skill_agreed = any([req.lower() in bot_utt for req in TRIGGER_PHRASES])
    lets_talk_about_asked = bool(lets_talk_about_check(vars))
    try:
        if not any([i in user_utt["text"].lower() for i in banned_words]):
            if linkto_food_skill_agreed:
                if is_yes(user_utt):
                    state_utils.set_confidence(vars, confidence=CONF_HIGH)
                    state_utils.set_can_continue(vars, continue_flag=MUST_CONTINUE)
                elif not is_no(user_utt):
                    state_utils.set_confidence(vars, confidence=CONF_MIDDLE)
                    state_utils.set_can_continue(vars, continue_flag=CAN_CONTINUE_PROMPT)
                elif is_no(user_utt):
                    state_utils.set_confidence(vars, confidence=CONF_HIGH)
                    state_utils.set_can_continue(vars, continue_flag=CAN_NOT_CONTINUE)
                    return ACKNOWLEDGEMENTS["cuisine"]
            elif lets_talk_about_asked:
                state_utils.set_confidence(vars, confidence=CONF_HIGH)
                state_utils.set_can_continue(vars, continue_flag=MUST_CONTINUE)
            else:
                state_utils.set_confidence(vars, confidence=CONF_LOW)
                state_utils.set_can_continue(vars, continue_flag=CAN_CONTINUE_SCENARIO)
            return "I'm a fan of Mediterranean cuisine dishes. What cuisine do you prefer?"
    except Exception as exc:
        logger.exception(exc)
        sentry_sdk.capture_exception(exc)
        return error_response(vars)
Beispiel #5
0
def provide_facts_response(ctx, actor, page_source, wiki_page):
    wiki = ctx.misc.get("wiki", {})
    user_uttr: dict = ctx.misc.get("agent", {}).get("dialog", {}).get("human_utterances", [{}])[-1]
    isyes = is_yes(user_uttr) or re.findall(CONTINUE_PATTERN, user_uttr["text"])
    response = ""
    cur_wiki_page = wiki.get("cur_wiki_page", "")
    if not cur_wiki_page:
        wiki["cur_wiki_page"] = wiki_page
        if page_source == "wikiHow":
            page_content = get_wikihow_content(wiki_page, wikihow_cache)
            wiki_page_content_list = preprocess_wikihow_page(page_content)
            memory["wiki_page_content"] = wiki_page_content_list
        elif page_source == "wikipedia":
            page_content = get_wikipedia_content(wiki_page)
            wiki_page_content_list = preprocess_wikipedia_page(wiki_page.lower(), [], page_content)
            memory["wiki_page_content"] = wiki_page_content_list
        logger.info(f"wiki_page {wiki_page}")

    used_wiki_page_nums_dict = wiki.get("used_wiki_page_nums", {})
    used_wiki_page_nums = used_wiki_page_nums_dict.get(wiki_page, [])
    wiki_page_content_list = memory.get("wiki_page_content", [])
    logger.info(f"response, used_wiki_page_nums {used_wiki_page_nums}")
    logger.info(f"response, wiki_page_content_list {wiki_page_content_list[:3]}")

    if wiki_page_content_list:
        for num, fact in enumerate(wiki_page_content_list):
            if num not in used_wiki_page_nums:
                facts_str = fact.get("facts_str", "")
                question = fact.get("question", "")
                response = f"{facts_str} {question}".strip().replace("  ", " ")
                used_wiki_page_nums.append(num)
                used_wiki_page_nums_dict[wiki_page] = used_wiki_page_nums
                wiki["used_wiki_page_nums"] = used_wiki_page_nums_dict
                break

        if len(wiki_page_content_list) == len(used_wiki_page_nums):
            if len(wiki_page_content_list) == len(used_wiki_page_nums):
                wiki["wiki_page"] = ""
                memory["wiki_page_content"] = []
    logger.info(f"response, final {response}")
    if response:
        if isyes:
            context.set_confidence(ctx, actor, 1.0)
            context.set_can_continue(ctx, actor, common_constants.MUST_CONTINUE)
        else:
            context.set_confidence(ctx, actor, 0.99)
            context.set_can_continue(ctx, actor, common_constants.CAN_CONTINUE_SCENARIO)
    else:
        context.set_confidence(ctx, actor, 0.0)
        context.set_can_continue(ctx, actor, common_constants.CAN_NOT_CONTINUE)
    if hasattr(ctx, "a_s"):
        processed_node = ctx.a_s.get("processed_node", ctx.a_s["next_node"])
        processed_node.response = response
        ctx.a_s["processed_node"] = processed_node
    else:
        processed_node = ctx.framework_states["actor"].get("processed_node", ctx.framework_states["actor"]["next_node"])
        processed_node.response = response
        ctx.framework_states["actor"]["processed_node"] = processed_node
    return ctx
Beispiel #6
0
def check_condition_element(elem, user_uttr, bot_uttr, shared_memory={}):
    flag = False
    annotations = user_uttr["annotations"]
    isyes = is_yes(user_uttr)
    isno = is_no(user_uttr)
    user_info = shared_memory.get("user_info", {})
    entity_triplets = shared_memory.get("entity_triplets", {})
    if elem[0] == "is_yes" and isyes:
        flag = True
    elif elem[0] == "is_no" and isno:
        flag = True
    elif "pattern" in elem[0]:
        pattern = elem[0]["pattern"]
        if elem[1] == "user" and (
            (isinstance(pattern, str)
             and re.findall(pattern, user_uttr["text"], re.IGNORECASE)) or
            (isinstance(pattern, re.Pattern)
             and re.findall(pattern, user_uttr["text"]))):
            flag = True
        if elem[1] == "bot" and (
            (isinstance(pattern, str)
             and re.findall(pattern, bot_uttr.get("text", ""), re.IGNORECASE))
                or (isinstance(pattern, re.Pattern)
                    and re.findall(pattern, bot_uttr.get("text", "")))):
            flag = True
    elif "cobot_entities_type" in elem[0]:
        cobot_entities_type = elem[0]["cobot_entities_type"]
        nounphrases = annotations.get("cobot_entities",
                                      {}).get("labelled_entities", [])
        for nounphr in nounphrases:
            nounphr_label = nounphr.get("label", "")
            if nounphr_label == cobot_entities_type:
                flag = True
    elif "wiki_parser_types" in elem[0]:
        wp_types = elem[0]["wiki_parser_types"]
        found_entity, *_ = find_entity_by_types(annotations, wp_types)
        if found_entity:
            flag = True
    elif "user_info" in elem[0]:
        info_to_check = elem[0]["user_info"]
        for key, value in info_to_check.items():
            if key in user_info and user_info[key] == value:
                flag = True
                break
    elif "entity_triplets" in elem[0]:
        checked_entity_triplets = elem[0]["entity_triplets"]
        objects = set(checked_entity_triplets[-1])
        mem_objects = entity_triplets
        for key in checked_entity_triplets[:-1]:
            if key in user_info:
                key = user_info[key]
            mem_objects = mem_objects.get(key, {})
        if set(mem_objects).intersection(objects):
            flag = True
    elif elem[0] == "any":
        flag = True
    if len(elem) == 3 and not elem[2]:
        flag = not flag
    return flag
Beispiel #7
0
def is_staying_home_requested(prev_bot_utt, user_utt):
    for phrase in [
            REMOTE_WORK_CORONAVIRUS_PHRASE, STAY_HOME_CORONAVIRUS_PHRASE
    ]:
        if phrase.lower() in prev_bot_utt.get("text", "").lower():
            if is_yes(user_utt) or is_no(user_utt):
                return True
    return False
Beispiel #8
0
def user_doesnt_say_yes_request(ngrams, vars, additional_check=None):
    uttr = state_utils.get_last_human_utterance(vars)
    flag = not is_yes(uttr) and perform_additional_check(
        additional_check, ngrams, vars)
    logger.info(
        f"user_doesnt_say_yes_request {get_additional_check_description(additional_check)}: {flag}"
    )
    return flag
Beispiel #9
0
def drawing_request(vars):
    flag = False
    user_uttr = state_utils.get_last_human_utterance(vars)
    bot_uttr = state_utils.get_last_bot_utterance(vars)
    isyes = is_yes(user_uttr)
    if re.findall("do you like drawing", bot_uttr.get("text", "")) and isyes:
        flag = True
    return flag
Beispiel #10
0
def is_speech_function_agree(vars):
    human_utterance = state_utils.get_last_human_utterance(vars)
    sf_type, sf_confidence = get_speech_function_for_human_utterance(
        human_utterance)
    flag = sf_type and bool(re.search(agree_patterns_re, sf_type))
    # fallback to yes/no intents
    flag = flag or common_utils.is_yes(human_utterance)

    return flag
Beispiel #11
0
def what_cuisine_request(ngrams, vars):
    linkto_food_skill_agreed = any(
        [req.lower() in state_utils.get_last_bot_utterance(vars)["text"].lower() for req in TRIGGER_PHRASES]
    ) and any(
        [is_yes(state_utils.get_last_human_utterance(vars)), not is_no(state_utils.get_last_human_utterance(vars))]
    )
    flag = (bool(lets_talk_about_check(vars)) or linkto_food_skill_agreed) and (not dont_want_talk(vars))
    logger.info(f"what_cuisine_request {flag}")
    return flag
Beispiel #12
0
def user_wants_game_description_2_or_more_of_description_turns_remain_request(
        ngrams, vars):
    flag = False
    user_uttr = state_utils.get_last_human_utterance(vars)
    isyes = is_yes(user_uttr)
    if not isyes:
        flag = True
    logger.info(
        f"user_wants_game_description_2_or_more_of_description_turns_remain_request={flag}"
    )
    return flag
Beispiel #13
0
def is_speech_function_demand_opinion(vars):
    human_utterance = state_utils.get_last_human_utterance(vars)
    sf_type, sf_confidence = get_speech_function_for_human_utterance(
        human_utterance)
    flag = sf_type and bool(re.search(demand_opinion_patterns_re, sf_type))
    # # fallback to CoBot intents
    flag = flag or is_cobot_opinion_demanded(vars)
    flag = flag or common_utils.is_no(human_utterance)
    # bug check (sometimes opinion by MIDAS can be incorrectly detected in a simple yes/no answer from user)
    flag = flag and not common_utils.is_no(
        human_utterance) and not common_utils.is_yes(human_utterance)
    return flag
Beispiel #14
0
def my_pets_request(ngrams, vars):
    flag = False
    bot_uttr = state_utils.get_last_bot_utterance(vars)["text"]
    isyes = is_yes(state_utils.get_last_human_utterance(vars))
    shared_memory = state_utils.get_shared_memory(vars)
    told_about_cat = shared_memory.get("told_about_cat", False)
    told_about_dog = shared_memory.get("told_about_dog", False)
    if "Would you like to learn more about my pets?" in bot_uttr and isyes and not (
            told_about_cat and told_about_dog):
        flag = True
    logger.info(f"my_pets_request={flag}")
    return flag
Beispiel #15
0
def is_speech_function_agree(vars):
    # fallback to MIDAS
    human_utterance = state_utils.get_last_human_utterance(vars)
    sf_type, sf_confidence = get_speech_function_for_human_utterance(
        human_utterance)
    flag = sf_type and bool(re.search(agree_patterns_re, sf_type))
    # fallback to MIDAS
    flag = flag or is_midas_positive_answer(vars)
    # fallback to yes/no intents
    flag = flag or common_utils.is_yes(human_utterance)

    flag = flag and not is_not_interested_speech_function(vars)
    return flag
Beispiel #16
0
def user_has_pets_request(ngrams, vars):
    flag = False
    user_uttr = state_utils.get_last_human_utterance(vars)["text"]
    bot_uttr = state_utils.get_last_bot_utterance(vars)["text"].lower()
    isno = is_no(state_utils.get_last_human_utterance(vars))
    isyes = is_yes(state_utils.get_last_human_utterance(vars))
    user_has = re.findall("i (have|had)", user_uttr)
    bot_asked_like = "do you like animals" in bot_uttr
    bot_asked_have = "do you have pets" in bot_uttr
    if ((re.search(PETS_TEMPLATE_EXT, user_uttr) and not isno)
            or (re.search(PETS_TEMPLATE_EXT, bot_uttr) and (isyes or user_has))
            or (bot_asked_like and user_has) or (bot_asked_have and isyes)):
        flag = True
    logger.info(f"user_has_pets_request={flag}")
    return flag
Beispiel #17
0
def check_cooking_request(ngrams, vars):
    linkto_food_skill_agreed = any(
        [req.lower() in state_utils.get_last_bot_utterance(vars)["text"].lower() for req in TRIGGER_PHRASES]
    ) and any(
        [
            is_yes(state_utils.get_last_human_utterance(vars)),
            not is_no(state_utils.get_last_human_utterance(vars)),
            bool(re.search(LIKE_RE, state_utils.get_last_human_utterance(vars)["text"].lower())),
        ]
    )
    if linkto_food_skill_agreed:
        flag = True
    else:
        flag = False
    logger.info(f"check_cooking_request {flag}")
    return flag
Beispiel #18
0
def check_condition(vars, condition):
    flag = False
    user_uttr = state_utils.get_last_human_utterance(vars)
    if callable(condition):
        flag = condition(vars)
    elif isinstance(condition, str):
        if re.findall(condition, user_uttr["text"], re.IGNORECASE):
            flag = True
    elif isinstance(condition, re.Pattern):
        if re.findall(condition, user_uttr["text"]):
            flag = True
    elif condition == intents.yes_intent(vars) and is_yes(user_uttr):
        flag = True
    elif condition == intents.always_true(vars):
        flag = True
    return flag
Beispiel #19
0
def if_wants_more(vars, all_titles):
    flag = False
    isyes = is_yes(state_utils.get_last_human_utterance(vars))
    isno = is_no(state_utils.get_last_human_utterance(vars))
    user_uttr = state_utils.get_last_human_utterance(vars)
    further = re.findall(r"(more|further|continue|follow)", user_uttr["text"],
                         re.IGNORECASE)
    another_topic = another_topic_question(vars, all_titles)
    if isyes or (further and not isno):
        flag = True
    if another_topic and not isyes:
        flag = False
    if isno:
        flag = False
    logger.info(f"wants_more={flag}")
    return flag
Beispiel #20
0
def sys_what_animals_request(ngrams, vars):
    flag = False
    linkto_like_animals = any([
        req.lower()
        in state_utils.get_last_bot_utterance(vars)["text"].lower()
        for req in LIKE_ANIMALS_REQUESTS
    ])
    text = state_utils.get_last_human_utterance(vars)["text"]
    user_agrees = is_yes(state_utils.get_last_human_utterance(vars))
    check_linkto = lets_talk_about_request(vars) or (
        linkto_like_animals and user_agrees) or text == "animals"
    find_pets = re.findall(r"(\bpet\b|\bpets\b)", text) or re.search(
        PETS_TEMPLATE, text)
    if check_linkto and not find_pets:
        flag = True
    logger.info(f"sys_what_animals_request={flag}")
    return flag
Beispiel #21
0
def user_mentioned_his_pet_request(ngrams, vars):
    flag = False
    user_uttr = state_utils.get_last_human_utterance(vars)
    bot_uttr = state_utils.get_last_bot_utterance(vars)
    isyes = is_yes(user_uttr)
    users_pet = re.findall(r"my (cat|dog|puppy|kitty|kitten)",
                           user_uttr["text"], re.IGNORECASE)
    has_pet = re.findall(r"i (have |had )(a )?(cat|dog|puppy|kitty|kitten)",
                         user_uttr["text"], re.IGNORECASE)
    found_badlist = re.findall(NOT_SWITCH_TEMPLATE, user_uttr["text"])
    bot_asked_pet = "do you have pets" in bot_uttr["text"].lower()
    found_pet = re.search(PETS_TEMPLATE, user_uttr["text"])
    if (users_pet or has_pet or (bot_asked_pet and
                                 (found_pet or isyes))) and not found_badlist:
        flag = True
    logger.info(f"user_mentioned_his_pet_request={flag}")
    return flag
Beispiel #22
0
def more_details_request(ngrams, vars):
    flag = False
    shared_memory = state_utils.get_shared_memory(vars)
    mentions_list = shared_memory.get("mentions", [])
    user_uttr = state_utils.get_last_human_utterance(vars)
    annotations = user_uttr["annotations"]
    bot_uttr = state_utils.get_last_bot_utterance(vars)
    bot_more_details = "more details" in bot_uttr["text"]
    user_more_details = re.findall(COMPILE_LETS_TALK, user_uttr["text"])
    isyes = is_yes(state_utils.get_last_human_utterance(vars))
    nounphrases = annotations.get("spacy_nounphrases", [])
    inters = set(nounphrases).intersection(set(mentions_list))
    started = shared_memory.get("start", False)
    if ((user_more_details and inters) or
        (bot_more_details and isyes)) and started:
        flag = True
    logger.info(f"more_details_request={flag}")
    return flag
Beispiel #23
0
def switch_to_general_gaming_discussion(vars):
    user_uttr = state_utils.get_last_human_utterance(vars)
    user_text = user_uttr.get("text", "").lower()
    prev_bot_uttr = state_utils.get_last_bot_utterance(vars)
    prev_bot_text = prev_bot_uttr.get("text", "")
    found_video_game_words_in_user_uttr = bool(
        VIDEO_GAME_WORDS_COMPILED_PATTERN.search(user_text))
    choose_gaming_discussion = if_choose_topic(
        user_uttr, prev_bot_uttr) and found_video_game_words_in_user_uttr
    question_answer_contains_video_game_words = (
        "?" not in user_text and "?" in prev_bot_text
        and found_video_game_words_in_user_uttr)
    bot_asked_about_game_and_user_answered_yes = is_yes(
        user_uttr) and is_question_about_games(prev_bot_text)
    flag = (lets_talk_about(vars, VIDEO_GAME_WORDS_COMPILED_PATTERN)
            or choose_gaming_discussion
            or question_answer_contains_video_game_words
            or bot_asked_about_game_and_user_answered_yes)
    logger.info(f"switch_to_general_gaming_discussion={flag}")
    return flag
Beispiel #24
0
def what_pets_request(ngrams, vars):
    flag = False
    bot_uttr = state_utils.get_last_bot_utterance(vars)
    user_uttr = state_utils.get_last_human_utterance(vars)
    isyes = is_yes(state_utils.get_last_human_utterance(vars))
    user_has = re.findall(r"i (have|had)", user_uttr["text"])
    mention_pet = re.findall(PETS_TEMPLATE, user_uttr["text"])
    asked_about_pets = "do you have pets" in bot_uttr["text"].lower()
    bot_asked_pet = re.findall(
        r"do you have a (cat|dog|rat|fish|bird|parrot|hamster)",
        bot_uttr["text"], re.IGNORECASE)
    logger.info(
        f"what_pets_request, {asked_about_pets}, {isyes}, {user_has}, {mention_pet}"
    )
    my_pets = my_pets_request(ngrams, vars)
    if not my_pets and asked_about_pets and (
            isyes or
            user_has) and not mention_pet and not (bot_asked_pet and is_yes):
        flag = True
    logger.info(f"what_pets_request={flag}")
    return flag
Beispiel #25
0
def retrieve_and_save(vars):
    user_uttr = state_utils.get_last_human_utterance(vars)["text"]
    bot_uttr = state_utils.get_last_bot_utterance(vars)["text"]
    isyes = is_yes(state_utils.get_last_human_utterance(vars))
    shared_memory = state_utils.get_shared_memory(vars)
    found_users_pet = shared_memory.get("users_pet", "")
    found_pet_bot_uttr = []
    if not found_users_pet:
        found_users_pet = extract_pet(user_uttr)
        found_pet_bot_uttr = re.findall(
            r"(do you have a )(cat|dog|rat|fish|bird|parrot|hamster|puppy|kitten|kitty)",
            bot_uttr, re.IGNORECASE)
        if found_users_pet:
            state_utils.save_to_shared_memory(vars, users_pet=found_users_pet)
        elif found_pet_bot_uttr and isyes:
            state_utils.save_to_shared_memory(
                vars, users_pet=found_pet_bot_uttr[0][1])
            found_users_pet = found_pet_bot_uttr[0][1]
    logger.info(
        f"retrieve_and_save, found_users_pet {found_users_pet} found_pet_bot_uttr {found_pet_bot_uttr}"
        f" isyes {isyes}")
    return found_users_pet
Beispiel #26
0
def user_wants_to_talk_about_minecraft_request(ngrams, vars):
    if common_intents.switch_to_particular_game_discussion(vars):
        user_uttr = state_utils.get_last_human_utterance(vars)
        prev_bot_uttr = state_utils.get_last_bot_utterance(vars)
        game_names_from_local_list_of_games = find_games_in_text(
            user_uttr.get("text", ""))
        if is_yes(user_uttr):
            game_names_from_local_list_of_games += find_games_in_text(
                prev_bot_uttr.get("text", ""))
        logger.info(
            f"(user_wants_to_talk_about_minecraft_request)game_names_from_local_list_of_games: "
            f"{game_names_from_local_list_of_games}")
        assert (
            game_names_from_local_list_of_games
        ), "At least one game should have been found in function `switch_to_particular_game_discussion()`"
        flag = any([
            "minecraft" in gn[0].lower()
            for gn in game_names_from_local_list_of_games
        ])
    else:
        flag = False
    logger.info(f"user_wants_to_talk_about_minecraft_request={flag}")
    return flag
Beispiel #27
0
def get_entities_with_attitudes(annotated_uttr: dict,
                                prev_annotated_uttr: dict):
    entities_with_attitudes = {"like": [], "dislike": []}
    all_entities = get_entities(annotated_uttr,
                                only_named=False,
                                with_labels=False)
    all_prev_entities = get_entities(prev_annotated_uttr,
                                     only_named=False,
                                     with_labels=False)
    logger.info(
        f"Consider all curr entities: {all_entities}, and all previous entities: {all_prev_entities}"
    )
    curr_entity = all_entities[0] if all_entities else ""
    prev_entity = all_prev_entities[-1] if all_prev_entities else ""
    curr_uttr_text = annotated_uttr.get("text", "")
    prev_uttr_text = prev_annotated_uttr.get("text", "")
    curr_sentiment = get_sentiment(annotated_uttr,
                                   probs=False,
                                   default_labels=["neutral"])[0]
    current_first_sentence = (annotated_uttr.get("annotations", {}).get(
        "sentseg", {}).get("segments", [curr_uttr_text])[0])

    if "?" in current_first_sentence:
        pass
    elif WHAT_FAVORITE_PATTERN.search(prev_uttr_text):
        # what is your favorite ..? - animals -> `like animals`
        entities_with_attitudes["like"] += [curr_entity]
    elif WHAT_LESS_FAVORITE_PATTERN.search(prev_uttr_text):
        # what is your less favorite ..? - animals -> `dislike animals`
        entities_with_attitudes["dislike"] += [curr_entity]
    elif DO_YOU_LOVE_PATTERN.search(prev_uttr_text):
        if is_no(annotated_uttr):
            # do you love .. animals? - no -> `dislike animals`
            entities_with_attitudes["dislike"] += [prev_entity]
        elif is_yes(annotated_uttr):
            # do you love .. animals? - yes -> `like animals`
            entities_with_attitudes["like"] += [prev_entity]
    elif DO_YOU_HATE_PATTERN.search(prev_uttr_text):
        if is_no(annotated_uttr):
            # do you hate .. animals? - no -> `like animals`
            entities_with_attitudes["like"] += [prev_entity]
        elif is_yes(annotated_uttr):
            # do you hate .. animals? - yes -> `dislike animals`
            entities_with_attitudes["dislike"] += [prev_entity]
    elif I_HATE_PATTERN.search(curr_uttr_text):
        # i hate .. animals -> `dislike animals`
        entities_with_attitudes["dislike"] += [curr_entity]
    elif I_LOVE_PATTERN.search(curr_uttr_text) or MY_FAVORITE_PATTERN.search(
            curr_uttr_text):
        # i love .. animals -> `like animals`
        entities_with_attitudes["like"] += [curr_entity]
    elif if_chat_about_particular_topic(
            annotated_uttr,
            prev_annotated_uttr=prev_annotated_uttr,
            key_words=[curr_entity]):
        # what do you want to chat about? - ANIMALS -> `like animals`
        entities_with_attitudes["like"] += [curr_entity]
    elif if_not_want_to_chat_about_particular_topic(
            annotated_uttr, prev_annotated_uttr=prev_annotated_uttr):
        # i don't wanna talk about animals -> `dislike animals`
        entities_with_attitudes["dislike"] += [curr_entity]
    elif WHAT_DO_YOU_THINK_PATTERN.search(prev_uttr_text):
        if curr_sentiment == "negative":
            # what do you thank .. animals? - negative -> `dislike animals`
            entities_with_attitudes["dislike"] += [prev_entity]
        elif curr_sentiment == "positive":
            # what do you thank .. animals? - positive -> `like animals`
            entities_with_attitudes["like"] += [prev_entity]

    entities_with_attitudes["like"] = [
        el for el in entities_with_attitudes["like"] if el
    ]
    entities_with_attitudes["dislike"] = [
        el for el in entities_with_attitudes["dislike"] if el
    ]
    return entities_with_attitudes
Beispiel #28
0
def if_chat_about_particular_topic(annotated_uttr,
                                   prev_annotated_uttr=None,
                                   key_words=None,
                                   compiled_pattern=r""):
    """Dialog context implies that the last utterances chooses particular conversational topic:
    - annotated_uttr asks "let's talk about PARTICULAR-TOPIC"
    - prev_annotated_uttr asks "what do you want to talk about?", and annotated_uttr says PARTICULAR-TOPIC.
    - prev_annotated_uttr asks "what are your interests?", and annotated_uttr says PARTICULAR-TOPIC.
    """
    prev_annotated_uttr = {} if prev_annotated_uttr is None else prev_annotated_uttr
    key_words = [] if key_words is None else key_words
    uttr_ = annotated_uttr.get("text", "").lower()
    prev_uttr_ = prev_annotated_uttr.get("text", "").lower()

    # current uttr is lets talk about blabla
    chat_about_intent = "lets_chat_about" in get_intents(
        annotated_uttr, probs=False, which="intent_catcher")
    chat_about = chat_about_intent or if_lets_chat_about_topic(uttr_)

    # prev uttr is what do you want to talk about?
    prev_chat_about_intent = "lets_chat_about" in get_intents(
        prev_annotated_uttr, probs=False, which="intent_catcher")
    prev_what_to_chat_about = prev_chat_about_intent or if_utterance_requests_topic(
        prev_annotated_uttr)

    not_want = if_not_want_to_chat_about_particular_topic(
        annotated_uttr, prev_annotated_uttr)
    if not_want:
        return False
    elif prev_what_to_chat_about or chat_about:
        if key_words:
            trigger_pattern = re.compile(
                rf"{join_word_beginnings_in_or_pattern(key_words)}[a-zA-Z0-9,\-\' ]+\?",
                re.IGNORECASE)
            offered_this_topic = trigger_pattern.search(prev_uttr_)
            user_agrees_or_any = ANY_TOPIC_AMONG_OFFERED.search(
                uttr_) or is_yes(annotated_uttr)
            if any([word in uttr_ for word in key_words
                    ]) or (offered_this_topic and user_agrees_or_any):
                return True
            else:
                return False
        elif compiled_pattern:
            if isinstance(compiled_pattern, str):
                offered_this_topic = re.search(
                    rf"{compiled_pattern}[a-zA-Z0-9,\-\' ]+\?", prev_uttr_,
                    re.IGNORECASE)
            else:
                offered_this_topic = re.search(
                    rf"{compiled_pattern.pattern}[a-zA-Z0-9,\-\' ]+\?",
                    prev_uttr_, re.IGNORECASE)
            user_agrees_or_any = ANY_TOPIC_AMONG_OFFERED.search(
                uttr_) or is_yes(annotated_uttr)
            if re.search(compiled_pattern, uttr_) or (offered_this_topic
                                                      and user_agrees_or_any):
                return True
            else:
                return False
        else:
            return True
    return False
Beispiel #29
0
def get_response_for_particular_topic_and_status(topic,
                                                 curr_meta_script_status,
                                                 dialog, source_topic):
    attr = {
        "meta_script_topic": topic,
        "meta_script_status": curr_meta_script_status
    }

    if len(dialog["human_utterances"]) > 0:
        user_uttr = dialog["human_utterances"][-1]
        text_user_uttr = dialog["human_utterances"][-1]["text"].lower()
        last_user_sent_text = (dialog["human_utterances"][-1].get(
            "annotations", {}).get("sentseg", {}).get("segments",
                                                      [""])[-1].lower())
    else:
        user_uttr = {"text": ""}
        text_user_uttr = ""
        last_user_sent_text = ""
    if len(dialog["bot_utterances"]) > 0:
        bot_uttr = dialog["bot_utterances"][-1]
    else:
        bot_uttr = {}
    if curr_meta_script_status == "starting":
        response, confidence, attr = get_starting_phrase(dialog, topic, attr)
        attr["response_parts"] = ["prompt"]
        can_offer_topic = if_choose_topic(dialog["human_utterances"][-1],
                                          bot_uttr)
        talk_about_user_topic = is_custom_topic(
            topic) and if_chat_about_particular_topic(user_uttr, bot_uttr)

        prev_what_to_talk_about_outputs = [
            get_outputs_with_response_from_dialog(dialog["utterances"][-3:],
                                                  response=response,
                                                  activated=True) for response
            in GREETING_QUESTIONS[list(GREETING_QUESTIONS.keys())[0]]
        ]
        prev_what_to_talk_about_outputs = sum([
            list_of_outputs
            for list_of_outputs in prev_what_to_talk_about_outputs
            if len(list_of_outputs) > 0
        ], [])
        prev_what_to_talk_about_greeting = len(
            prev_what_to_talk_about_outputs) > 0 and bot_uttr.get(
                "active_skill", "") in ["dff_friendship_skill", "program_y"]

        if (not prev_what_to_talk_about_greeting
                and can_offer_topic) or talk_about_user_topic:
            # if person wants to talk about something particular and we have extracted some topic - do that!
            confidence = MATCHED_DIALOG_BEGIN_CONFIDENCE
        elif "?" in last_user_sent_text or prev_what_to_talk_about_greeting:
            # if some question was asked by user, do not start script at all!
            response, confidence = "", 0.0
        elif len(dialog["utterances"]) <= 20:
            confidence = DEFAULT_DIALOG_BEGIN_CONFIDENCE
        elif source_topic == NP_SOURCE:
            confidence = NOUN_TOPIC_STARTING_CONFIDENCE
        else:
            confidence = DEFAULT_STARTING_CONFIDENCE
    else:
        if curr_meta_script_status == "deeper1" and "?" in last_user_sent_text and "what" not in text_user_uttr:
            response, confidence, attr = "", 0.0, {}
        elif "?" in last_user_sent_text and not check_topic_lemmas_in_sentence(
                text_user_uttr, topic):
            logger.info(
                "Question by user was detected. Without any word from topic in it. "
                "Don't continue the script on this turn.")
            response, confidence, attr = "", 0.0, {}
        elif is_switch_topic(user_uttr) or if_chat_about_particular_topic(
                user_uttr):
            logger.info("Topic switching was detected. Finish script.")
            response, confidence = FINISHED_SCRIPT_RESPONSE, 0.5
            attr["meta_script_status"] = FINISHED_SCRIPT
            attr["can_continue"] = CAN_NOT_CONTINUE
        elif get_user_replies_to_particular_skill(
                dialog["utterances"],
                "meta_script_skill")[-2:] == ["no.", "no."]:
            logger.info(
                "Two consequent `no` answers were detected. Finish script.")
            response, confidence = FINISHED_SCRIPT_RESPONSE, 0.5
            attr["meta_script_status"] = FINISHED_SCRIPT
            attr["can_continue"] = CAN_NOT_CONTINUE
        elif curr_meta_script_status == "comment":
            response, confidence, attr = get_comment_phrase(dialog, attr)
            attr["can_continue"] = CAN_NOT_CONTINUE
        elif curr_meta_script_status == "opinion":
            response, confidence, attr = get_opinion_phrase(
                dialog, topic, attr)
        elif curr_meta_script_status == "deeper1" and (
                is_no(user_uttr) or "never" in text_user_uttr):
            response, confidence = FINISHED_SCRIPT_RESPONSE, 0.5
            attr["meta_script_status"] = FINISHED_SCRIPT
            attr["can_continue"] = CAN_NOT_CONTINUE
        else:
            response, confidence, attr = get_statement_phrase(
                dialog, topic, attr, TOPICS)
            attr["can_continue"] = CAN_CONTINUE_SCENARIO

        if confidence > 0.7 and (is_yes(user_uttr)
                                 or len(text_user_uttr.split()) > 7):
            # if yes detected, confidence 1.0 - we like agreements!
            confidence = 1.0
        if confidence > 0.7 and bot_uttr.get("active_skill",
                                             "") != "meta_script_skill":
            confidence = BROKEN_DIALOG_CONTINUE_CONFIDENCE

    logger.info(
        f"User sent: `{text_user_uttr}`. Response: `{response}`. Attr: `{attr}.`"
    )
    return response, confidence, attr
Beispiel #30
0
def misheard_response():
    st_time = time.time()
    dialogs_batch = request.json["dialogs"]
    final_confidences = []
    final_responses = []
    final_human_attributes = []
    final_bot_attributes = []

    for dialog in dialogs_batch:
        prev_user_utt = None
        if len(dialog["human_utterances"]) > 1:
            prev_user_utt = dialog["human_utterances"][-2]
        bot_attributes = dialog["bot"]["attributes"]
        human_attributes = dialog["human"]["attributes"]
        current_user_utt = dialog["human_utterances"][-1]
        prev_bot_utt = dialog["bot_utterances"][-1] if len(
            dialog["bot_utterances"]) > 0 else {}
        logger.debug(
            f"MISHEARD ASR INPUT: current utt text: {current_user_utt['text']};"
            f"bot attrs: {bot_attributes}; user attrs: {human_attributes}"
            f"HYPOTS: {current_user_utt['hypotheses']}"
            f"PREV BOT UTT: {prev_bot_utt}")
        if bot_attributes.get("asr_misheard") is True and prev_bot_utt[
                "active_skill"] == "misheard_asr":
            bot_attributes["asr_misheard"] = False
            if is_yes(current_user_utt):
                hypots = prev_user_utt["hypotheses"]
                logger.debug(f"PREV HYPOTS: {hypots}")
                candidates = []
                confs = []
                for resp in hypots:
                    if resp["skill_name"] != "misheard_asr":
                        candidates.append(resp["text"])
                        confs.append(resp["confidence"])
                final_responses.append(candidates)
                final_confidences.append(confs)
                final_human_attributes.append([human_attributes] *
                                              len(candidates))
                final_bot_attributes.append([bot_attributes] * len(candidates))
            elif is_no(current_user_utt):
                response = "What is it that you'd like to chat about?"
                final_responses.append([response])
                final_confidences.append([1.0])
                final_human_attributes.append([human_attributes])
                final_bot_attributes.append([bot_attributes])
            else:
                final_responses.append(["sorry"])
                final_confidences.append([0.0])
                final_human_attributes.append([human_attributes])
                final_bot_attributes.append([bot_attributes])
        else:
            bot_attributes["asr_misheard"] = False
            if current_user_utt["annotations"]["asr"][
                    "asr_confidence"] == "very_low":
                final_responses.append([np.random.choice(misheard_responses)])
                final_confidences.append([1.0])
                final_human_attributes.append([human_attributes])
                final_bot_attributes.append([bot_attributes])
            elif current_user_utt["annotations"]["asr"][
                    "asr_confidence"] == "medium":
                response = f"Excuse me, I misheard you. Have you said: \"{dialog['human_utterances'][-1]['text']}\"?"
                final_responses.append([response])
                final_confidences.append([1.0])
                bot_attributes["asr_misheard"] = True
                final_human_attributes.append([human_attributes])
                final_bot_attributes.append([bot_attributes])
            else:
                final_responses.append(["sorry"])
                final_confidences.append([0.0])
                final_human_attributes.append([human_attributes])
                final_bot_attributes.append([bot_attributes])

    total_time = time.time() - st_time
    logger.info(f"misheard_asr#misheard_respond exec time: {total_time:.3f}s")
    resp = list(
        zip(final_responses, final_confidences, final_human_attributes,
            final_bot_attributes))
    logger.debug(f"misheard_asr#misheard_respond OUTPUT: {resp}")
    return jsonify(resp)