dream
1105 строк · 45.7 Кб
1# %%
2import json3import logging4import os5import random6import re7
8from common.fact_random import get_fact9from enum import Enum, auto10
11import sentry_sdk12from spacy import load13
14from dff import dialogflow_extension15import common.dialogflow_framework.utils.state as state_utils16import common.dialogflow_framework.utils.condition as condition_utils17import dialogflows.scopes as scopes18from common.universal_templates import if_chat_about_particular_topic, DONOTKNOW_LIKE, COMPILE_NOT_WANT_TO_TALK_ABOUT_IT19from common.constants import CAN_CONTINUE_SCENARIO, CAN_CONTINUE_PROMPT, MUST_CONTINUE, CAN_NOT_CONTINUE20from common.utils import is_yes, is_no, get_entities, join_words_in_or_pattern, get_comet_conceptnet_annotations21from common.food import (22TRIGGER_PHRASES,23FOOD_WORDS,24WHAT_COOK,25FOOD_UTTERANCES_RE,26CUISINE_UTTERANCES_RE,27CONCEPTNET_SYMBOLOF_FOOD,28CONCEPTNET_HASPROPERTY_FOOD,29CONCEPTNET_CAUSESDESIRE_FOOD,30ACKNOWLEDGEMENTS,31FOOD_FACT_ACKNOWLEDGEMENTS,32)
33from common.link import link_to_skill2i_like_to_talk34from dialogflows.flows.fast_food import State as FFState35from dialogflows.flows.fast_food import fast_food_request36
37
38sentry_sdk.init(dsn=os.getenv("SENTRY_DSN"))39
40
41logger = logging.getLogger(__name__)42
43
44spacy_nlp = load("en_core_web_sm")45
46
47with open("cuisines_facts.json", "r") as f:48CUISINES_FACTS = json.load(f)49
50FOOD_WORDS_RE = re.compile(FOOD_WORDS, re.IGNORECASE)51WHAT_COOK_RE = re.compile(WHAT_COOK, re.IGNORECASE)52DONOTKNOW_LIKE_RE = re.compile(join_words_in_or_pattern(DONOTKNOW_LIKE), re.IGNORECASE)53NO_WORDS_RE = re.compile(r"(\bnot\b|n't|\bno\b) ", re.IGNORECASE)54# FAV_RE = re.compile(r"favou?rite|like", re.IGNORECASE)
55LIKE_RE = re.compile(r"\bi (like|love|adore)( to (bake|cook|eat)|)", re.IGNORECASE)56
57MEALS = [58"lazagna",59"mac and cheese",60"instant pot beef chili",61"tomato basil soup",62"spaghetti with tomato sauce",63"chicken noodle soup",64"rice with chicken and salad",65"potatoes with cheese and beans",66"fries with beef and tomatoes",67"quinoa with turkey and broccoli",68]
69CUISINES_COUNTRIES = {70"french": "France",71"chinese": "China",72"japanese": "Japan",73"italian": "Italy",74"greek": "Greece",75"spanish": "Spain",76"mediterranean": "Italy",77"thai": "Thailand",78"indian": "India",79"mexican": "Mexico",80}
81CONF_HIGH = 1.082CONF_MIDDLE = 0.9583CONF_LOW = 0.984CONF_LOWEST = 0.885
86
87class State(Enum):88USR_START = auto()89#90SYS_WHAT_COOK = auto()91SYS_WHAT_FAV_FOOD = auto()92SYS_WHAT_CUISINE = auto()93USR_WHAT_FAV_FOOD = auto()94SYS_FAV_FOOD = auto()95USR_WHAT_CUISINE = auto()96SYS_CUISINE = auto()97USR_CUISINE_FACT = auto()98USR_HOW_ABOUT_MEAL1 = auto()99SYS_YES_RECIPE = auto()100SYS_NO_RECIPE1 = auto()101SYS_NO_RECIPE2 = auto()102USR_RECIPE = auto()103USR_HOW_ABOUT_MEAL2 = auto()104USR_GOURMET = auto()105USR_FOOD_FACT = auto()106SYS_YES_FOOD_FACT = auto()107SYS_NO_FOOD_FACT = auto()108SYS_SOMETHING = auto()109USR_WHERE_R_U_FROM = auto()110SYS_TO_TRAVEL_SKILL = auto()111USR_COUNTRY = auto()112SYS_BOT_PERSONA_FAV_FOOD = auto()113SYS_SAID_FAV_FOOD = auto()114SYS_CHECK_COOKING = auto()115USR_SUGGEST_COOK = auto()116SYS_YES_COOK = auto()117SYS_NO_COOK = auto()118SYS_ENSURE_FOOD = auto()119SYS_LINKTO_PLUS_NO = auto()120SYS_LINKTO_PLUS_NO_RECIPE = auto()121SYS_MORE_FACTS = auto()122#123SYS_ERR = auto()124USR_ERR = auto()125
126
127# %%
128
129##################################################################################################################
130# Init DialogFlow
131##################################################################################################################
132
133
134simplified_dialogflow = dialogflow_extension.DFEasyFilling(State.USR_START)135
136##################################################################################################################
137##################################################################################################################
138# Design DialogFlow.
139##################################################################################################################
140##################################################################################################################
141##################################################################################################################
142# yes
143##################################################################################################################
144
145
146def yes_request(ngrams, vars):147flag = condition_utils.is_yes_vars(vars)148logger.info(f"yes_request {flag}")149return flag150
151
152##################################################################################################################
153# no
154##################################################################################################################
155
156
157def no_request(ngrams, vars):158flag = condition_utils.is_no_vars(vars)159logger.info(f"no_request {flag}")160return flag161
162
163def dont_want_talk(vars):164utt = state_utils.get_last_human_utterance(vars)["text"]165flag = bool(re.search(COMPILE_NOT_WANT_TO_TALK_ABOUT_IT, utt))166logger.info(f"dont_want_talk {flag}")167return flag168
169
170##################################################################################################################
171# error
172##################################################################################################################
173
174
175def error_response(vars):176state_utils.set_confidence(vars, 0)177return "Sorry"178
179
180##################################################################################################################
181# let's talk about food
182##################################################################################################################
183
184
185def is_question(vars):186annotations_sentseg = state_utils.get_last_human_utterance(vars)["annotations"].get("sentseg", {})187flag = "?" in annotations_sentseg.get("punct_sent", "")188return flag189
190
191def check_conceptnet(vars):192annotations_conceptnet = get_comet_conceptnet_annotations(state_utils.get_last_human_utterance(vars))193conceptnet = False194food_item = None195for elem, triplets in annotations_conceptnet.items():196symbol_of = triplets.get("SymbolOf", [])197conceptnet_symbolof = any(198[i in symbol_of for i in CONCEPTNET_SYMBOLOF_FOOD] + ["chicken" in i for i in symbol_of]199)200has_property = triplets.get("HasProperty", [])201conceptnet_hasproperty = any([i in has_property for i in CONCEPTNET_HASPROPERTY_FOOD])202causes_desire = triplets.get("CausesDesire", [])203conceptnet_causesdesire = any(204[i in causes_desire for i in CONCEPTNET_CAUSESDESIRE_FOOD]205+ ["eat" in i for i in causes_desire]206+ ["cook" in i for i in causes_desire]207+ ["food" in i for i in causes_desire]208)209conceptnet = any([conceptnet_symbolof, conceptnet_hasproperty, conceptnet_causesdesire])210if conceptnet:211food_item = elem212return conceptnet, food_item213return conceptnet, food_item214
215
216def lets_talk_about_check(vars):217# user_lets_chat_about = (218# "lets_chat_about" in get_intents(state_utils.get_last_human_utterance(vars), which="intent_catcher")219# or if_chat_about_particular_topic(state_utils.get_last_human_utterance(vars), prev_uttr)220# )221human_utt = state_utils.get_last_human_utterance(vars)222bot_utt = state_utils.get_last_bot_utterance(vars)223# if "weather" in human_utt["text"].lower():224# flag = ""225# logger.info(f"lets_talk_about_check {flag}, weather detected")226# return flag227if dont_want_talk(vars):228flag = ""229elif if_chat_about_particular_topic(human_utt, bot_utt, compiled_pattern=FOOD_WORDS_RE):230flag = "if_chat_about_particular_topic"231elif bool(re.search(FOOD_WORDS_RE, human_utt["text"])):232flag = "FOOD_WORDS_RE"233elif bool(re.search(FOOD_UTTERANCES_RE, bot_utt["text"])):234flag = "FOOD_UTTERANCES_RE"235elif bool(re.search(CUISINE_UTTERANCES_RE, bot_utt["text"])):236flag = "CUISINE_UTTERANCES_RE"237elif check_conceptnet(vars)[0]:238flag = "check_conceptnet"239elif bool(re.search(DONOTKNOW_LIKE_RE, human_utt["text"])):240flag = "DONOTKNOW_LIKE_RE"241else:242flag = ""243# user_lets_chat_about_food = any(244# [245# bool(re.search(FOOD_WORDS_RE, human_utt["text"].lower())),246# if_chat_about_particular_topic(human_utt, bot_utt, compiled_pattern=FOOD_WORDS_RE),247# check_conceptnet(vars)[0],248# bool(re.search(FOOD_SKILL_TRANSFER_PHRASES_RE, human_utt["text"].lower())),249# bool(re.search(DONOTKNOW_LIKE_RE, human_utt["text"].lower()))250# ]251# )252# and (not state_utils.get_last_human_utterance(vars)["text"].startswith("what"))253# flag = user_lets_chat_about_food254logger.info(f"lets_talk_about_check {flag}")255return flag256
257
258def what_cuisine_response(vars):259user_utt = state_utils.get_last_human_utterance(vars)260bot_utt = state_utils.get_last_bot_utterance(vars)["text"].lower()261banned_words = ["water"]262linkto_food_skill_agreed = any([req.lower() in bot_utt for req in TRIGGER_PHRASES])263lets_talk_about_asked = bool(lets_talk_about_check(vars))264try:265if not any([i in user_utt["text"].lower() for i in banned_words]):266if linkto_food_skill_agreed:267if is_yes(user_utt):268state_utils.set_confidence(vars, confidence=CONF_HIGH)269state_utils.set_can_continue(vars, continue_flag=MUST_CONTINUE)270elif not is_no(user_utt):271state_utils.set_confidence(vars, confidence=CONF_MIDDLE)272state_utils.set_can_continue(vars, continue_flag=CAN_CONTINUE_PROMPT)273elif is_no(user_utt):274state_utils.set_confidence(vars, confidence=CONF_HIGH)275state_utils.set_can_continue(vars, continue_flag=CAN_NOT_CONTINUE)276return ACKNOWLEDGEMENTS["cuisine"]277elif lets_talk_about_asked:278state_utils.set_confidence(vars, confidence=CONF_HIGH)279state_utils.set_can_continue(vars, continue_flag=MUST_CONTINUE)280else:281state_utils.set_confidence(vars, confidence=CONF_LOW)282state_utils.set_can_continue(vars, continue_flag=CAN_CONTINUE_SCENARIO)283return "I'm a fan of Mediterranean cuisine dishes. What cuisine do you prefer?"284except Exception as exc:285logger.exception(exc)286sentry_sdk.capture_exception(exc)287return error_response(vars)288
289
290def cuisine_request(ngrams, vars):291# nounphr = get_entities(state_utils.get_last_human_utterance(vars), only_named=False, with_labels=False)292# flag = bool(nounphr)293utt = state_utils.get_last_human_utterance(vars)["text"].lower()294spacy_utt = spacy_nlp(utt)295utt_adj = any([w.pos_ == "ADJ" for w in spacy_utt])296all_words = any([i in utt for i in ["all", "many", "multiple"]])297flag = any([utt_adj, check_conceptnet(vars)[0], all_words]) and (298not any([bool(re.search(NO_WORDS_RE, utt)), dont_want_talk(vars)])299)300logger.info(f"cuisine_request {flag}")301return flag302
303
304def cuisine_fact_response(vars):305cuisine_fact = ""306try:307state_utils.set_confidence(vars, confidence=CONF_MIDDLE)308last_utt = state_utils.get_last_human_utterance(vars)309last_utt_lower = last_utt["text"].lower()310conceptnet_flag, food_item = check_conceptnet(vars)311if any([w.pos_ == "ADJ" for w in spacy_nlp(last_utt_lower)]):312for cuisine in list(CUISINES_FACTS.keys()):313if cuisine in last_utt_lower:314cuisine_fact = CUISINES_FACTS.get(cuisine, "")315state_utils.save_to_shared_memory(vars, cuisine=cuisine)316state_utils.set_can_continue(vars, continue_flag=CAN_CONTINUE_SCENARIO)317return cuisine_fact318if not cuisine_fact:319state_utils.set_can_continue(vars, continue_flag=CAN_CONTINUE_SCENARIO)320response = "You have such a refined taste in food! "321"I haven't tried it yet. What do you recommend to start with?"322state_utils.add_acknowledgement_to_response_parts(vars)323return response324elif conceptnet_flag:325entity_linking = last_utt["annotations"].get("entity_linking", [])326if entity_linking:327_facts = entity_linking[0].get("entity_pages", [])328if _facts:329state_utils.set_can_continue(vars, continue_flag=CAN_CONTINUE_SCENARIO)330response = f"You're a gourmet! I know about {food_item} that {_facts[0]}"331state_utils.add_acknowledgement_to_response_parts(vars)332return response333else:334return ""335else:336state_utils.set_can_continue(vars, continue_flag=CAN_CONTINUE_SCENARIO)337return (338"My favorite cuisine is French. I'm just in love "339"with pastry, especially with profiteroles! How about you?"340)341else:342state_utils.set_can_continue(vars, continue_flag=CAN_CONTINUE_SCENARIO)343return (344"My favorite cuisine is French. I'm just in love "345"with pastry, especially with profiteroles! How about you?"346)347except Exception as exc:348logger.exception(exc)349sentry_sdk.capture_exception(exc)350return error_response(vars)351
352
353def country_response(vars):354shared_memory = state_utils.get_shared_memory(vars)355cuisine_discussed = shared_memory.get("cuisine", "")356try:357if cuisine_discussed:358if cuisine_discussed in CUISINES_COUNTRIES:359state_utils.set_confidence(vars, confidence=CONF_MIDDLE)360state_utils.set_can_continue(vars, continue_flag=CAN_NOT_CONTINUE)361return f"Have you ever been in {CUISINES_COUNTRIES[cuisine_discussed]}?"362else:363state_utils.set_can_continue(vars, continue_flag=CAN_NOT_CONTINUE)364return error_response(vars)365else:366state_utils.set_can_continue(vars, continue_flag=CAN_NOT_CONTINUE)367return error_response(vars)368except Exception as exc:369logger.exception(exc)370sentry_sdk.capture_exception(exc)371return error_response(vars)372
373
374def to_travel_skill_request(ngrams, vars):375flag = False376shared_memory = state_utils.get_shared_memory(vars)377cuisine_discussed = shared_memory.get("cuisine", "")378if cuisine_discussed:379if cuisine_discussed in CUISINES_COUNTRIES:380flag = True381logger.info(f"to_travel_skill_request {flag}")382return flag383
384
385def what_fav_food_response(vars):386food_types = {387"food": [388"lava cake",389"This cake is delicious, decadent, addicting, divine, just so incredibly good!!!"390" Soft warm chocolate cake outside giving way to a creamy, smooth stream of warm "391"liquid chocolate inside, ensuring every forkful is bathed in velvety chocolate. "392"It is my love at first bite.",393],394"drink": [395"orange juice",396"Isually I drink it at breakfast - it’s sweet with natural sugar for quick energy."397" Oranges have lots of vitamins and if you drink it with pulp, it has fiber. Also,"398" oranges are rich in vitamin C that keeps your immune system healthy.",399],400"fruit": [401"mango",402"Every year I wait for the summers so that I can lose myself in the aroma of perfectly"403" ripened mangoes and devour its heavenly sweet taste. Some people prefer mangoes which"404" are tangy and sour. However, I prefer sweet ones that taste like honey.",405],406"dessert": [407"profiteroles",408"Cream puffs of the size of a hamburger on steroids, the two pate a choux ends"409" showcased almost two cups of whipped cream - light, fluffy, and fresh. "410"There is nothing better than choux pastry!",411],412"vegetable": [413"broccoli",414"This hearty and tasty vegetable is rich in dozens of nutrients. It is said "415"to pack the most nutritional punch of any vegetable. When I think about green"416" vegetables to include in my diet, broccoli is one of the foremost veggies to "417"come to my mind.",418],419"berry": [420"blueberry",421"Fresh blueberries are delightful and have a slightly sweet taste that is mixed"422" with a little bit of acid from the berry. When I bite down on a blueberry,"423" I enjoy a burst of juice as the berry pops, and this juice is very sweet. "424"Blueberries are the blues that make you feel good!",425],426"snack": [427"peanut butter",428"It tastes great! Creamy, crunchy or beyond the jar, there is a special place "429"among my taste receptors for that signature peanutty flavor. I always gravitate"430" toward foods like peanut butter chocolate cheesecake, and peanut butter cottage"431" cookies. There are so many peanut butter flavored items for all kinds of food products!"432" Still, sometimes it’s best delivered on a spoon.",433],434}435user_utt = state_utils.get_last_human_utterance(vars)436bot_utt = state_utils.get_last_bot_utterance(vars)["text"].lower()437question = ""438shared_memory = state_utils.get_shared_memory(vars)439used_food = shared_memory.get("used_food", [])440unused_food = []441linkto_food_skill_agreed = any(442[req.lower() in state_utils.get_last_bot_utterance(vars)["text"].lower() for req in TRIGGER_PHRASES]443)444lets_talk_about_asked = lets_talk_about_check(vars)445try:446if used_food:447unused_food = [i for i in food_types.keys() if i not in used_food]448if unused_food:449food_type = random.choice(unused_food)450else:451state_utils.set_can_continue(vars, continue_flag=CAN_NOT_CONTINUE)452return error_response(vars)453else:454food_type = "food"455
456if linkto_food_skill_agreed:457if is_yes(user_utt):458if food_type == "food":459state_utils.set_confidence(vars, confidence=CONF_HIGH)460state_utils.set_can_continue(vars, continue_flag=MUST_CONTINUE)461elif food_type == "snack":462state_utils.set_confidence(vars, confidence=CONF_LOWEST)463state_utils.set_can_continue(vars, continue_flag=CAN_CONTINUE_SCENARIO)464elif unused_food:465state_utils.set_confidence(vars, confidence=CONF_MIDDLE)466state_utils.set_can_continue(vars, continue_flag=CAN_CONTINUE_SCENARIO)467else:468state_utils.set_confidence(vars, confidence=CONF_LOWEST)469state_utils.set_can_continue(vars, continue_flag=CAN_CONTINUE_SCENARIO)470
471elif not is_no(user_utt):472state_utils.set_confidence(vars, confidence=CONF_LOW)473state_utils.set_can_continue(vars, continue_flag=CAN_CONTINUE_SCENARIO)474elif is_no(user_utt):475state_utils.set_confidence(vars, confidence=CONF_HIGH)476state_utils.set_can_continue(vars, continue_flag=CAN_NOT_CONTINUE)477return ACKNOWLEDGEMENTS["fav_food_cook"]478
479elif bool(lets_talk_about_asked):480if (food_type == "food") or (lets_talk_about_asked == "if_chat_about_particular_topic"):481state_utils.set_confidence(vars, confidence=CONF_HIGH)482state_utils.set_can_continue(vars, continue_flag=MUST_CONTINUE)483elif food_type == "snack":484state_utils.set_confidence(vars, confidence=CONF_LOWEST)485state_utils.set_can_continue(vars, continue_flag=CAN_CONTINUE_SCENARIO)486elif unused_food:487state_utils.set_confidence(vars, confidence=CONF_MIDDLE)488state_utils.set_can_continue(vars, continue_flag=CAN_CONTINUE_SCENARIO)489else:490state_utils.set_confidence(vars, confidence=CONF_LOWEST)491state_utils.set_can_continue(vars, continue_flag=CAN_CONTINUE_SCENARIO)492else:493state_utils.set_confidence(vars, confidence=CONF_LOW)494state_utils.set_can_continue(vars, continue_flag=CAN_CONTINUE_SCENARIO)495
496state_utils.save_to_shared_memory(vars, used_food=used_food + [food_type])497fav_item = food_types.get(food_type, [])498if fav_item:499if food_type != "drink":500if "what is your favorite food" in bot_utt:501question = f" What {food_type} do you like?"502else:503question = " What is a typical meal from your country?"504return f"I like to eat {fav_item[0]}. {fav_item[1]}" + question505else:506if "what is your favorite food" in bot_utt:507question = f" What {food_type} do you prefer?"508else:509question = " What do you usually like to drink when you go out?"510return f"I like to drink {fav_item[0]}. {fav_item[1]}" + question511else:512state_utils.set_can_continue(vars, continue_flag=CAN_NOT_CONTINUE)513return error_response(vars)514except Exception as exc:515logger.exception(exc)516sentry_sdk.capture_exception(exc)517return error_response(vars)518
519
520def fav_food_check(vars):521flag = False522user_fav_food = get_entities(state_utils.get_last_human_utterance(vars), only_named=False, with_labels=False)523# cobot_topic = "Food_Drink" in get_topics(state_utils.get_last_human_utterance(vars), which="cobot_topics")524food_words_search = bool(re.search(FOOD_WORDS_RE, state_utils.get_last_human_utterance(vars)["text"]))525if all(526[527any([user_fav_food, check_conceptnet(vars), food_words_search]),528# condition_utils.no_requests(vars),529not bool(re.search(NO_WORDS_RE, state_utils.get_last_human_utterance(vars)["text"])),530not dont_want_talk(vars),531]532):533flag = True534logger.info(f"fav_food_check {flag}")535return flag536
537
538def fav_food_request(ngrams, vars):539flag = fav_food_check(vars)540logger.info(f"fav_food_request {flag}")541return flag542
543
544def food_fact_response(vars):545human_utt = state_utils.get_last_human_utterance(vars)546annotations = human_utt["annotations"]547human_utt_text = human_utt["text"].lower()548bot_utt_text = state_utils.get_last_bot_utterance(vars)["text"]549shared_memory = state_utils.get_shared_memory(vars)550used_facts = shared_memory.get("used_facts", [])551
552fact = ""553facts = []554entity = ""555berry_name = ""556
557linkto_check = any([linkto in bot_utt_text for linkto in link_to_skill2i_like_to_talk["dff_food_skill"]])558black_list_check = any(list(annotations.get("badlisted_words", {}).values()))559conceptnet_flag, food_item = check_conceptnet(vars)560
561entities_facts = annotations.get("fact_retrieval", {}).get("topic_facts", [])562for entity_facts in entities_facts:563if entity_facts["entity_type"] in ["food", "fruit", "vegetable", "berry"]:564if entity_facts["facts"]:565facts = entity_facts["facts"][0].get("sentences", [])566entity = entity_facts["entity_substr"]567else:568facts = []569
570if not facts:571facts = annotations.get("fact_random", [])572
573if black_list_check:574state_utils.set_can_continue(vars, continue_flag=CAN_NOT_CONTINUE)575return error_response(vars)576elif conceptnet_flag and all(["shower" not in human_utt_text, " mela" not in human_utt_text]):577if "berry" in bot_utt_text.lower():578berry_names = get_entities(state_utils.get_last_human_utterance(vars), only_named=False, with_labels=False)579if berry_names:580berry_name = berry_names[0]581
582if all(["berr" not in human_utt_text, len(human_utt_text.split()) == 1, berry_name]):583berry_name += "berry"584fact = get_fact(berry_name, f"fact about {berry_name}")585entity = berry_name586elif berry_name:587if facts and entity:588fact = random.choice([i for i in facts if i not in used_facts])589# facts[0]590elif facts:591for facts_item in facts:592if all(593[594facts_item.get("entity_substr", "xxx") in food_item,595facts_item.get("fact", "") not in used_facts,596]597):598fact = facts_item.get("fact", "")599entity = facts_item.get("entity_substr", "")600break601else:602fact = ""603entity = ""604else:605if all([facts, entity, entity in food_item]):606fact = random.choice([i for i in facts if i not in used_facts])607# facts[0]608elif facts and not entity:609for facts_item in facts:610if all(611[612facts_item.get("entity_substr", "xxx") in food_item,613facts_item.get("fact", "") not in used_facts,614]615):616fact = facts_item.get("fact", "")617entity = facts_item.get("entity_substr", "")618break619else:620fact = ""621entity = ""622else:623fact = ""624entity = ""625acknowledgement = random.choice(FOOD_FACT_ACKNOWLEDGEMENTS).replace("ENTITY", entity.lower())626state_utils.save_to_shared_memory(vars, used_facts=used_facts + [fact])627
628try:629if bot_persona_fav_food_check(vars) or len(state_utils.get_last_human_utterance(vars)["text"].split()) == 1:630state_utils.set_confidence(vars, confidence=CONF_HIGH)631else:632state_utils.set_confidence(vars, confidence=CONF_MIDDLE)633if bool(re.search(DONOTKNOW_LIKE_RE, human_utt_text)):634state_utils.set_confidence(vars, confidence=CONF_MIDDLE)635state_utils.set_can_continue(vars, continue_flag=CAN_CONTINUE_SCENARIO)636return "Well, as for me, I am a fan of pizza despite I cannot eat as humans."637elif any([dont_want_talk(vars), bool(re.search(NO_WORDS_RE, human_utt_text))]):638state_utils.set_can_continue(vars, continue_flag=CAN_NOT_CONTINUE)639return error_response(vars)640elif (not fact) and conceptnet_flag:641state_utils.set_can_continue(vars, continue_flag=CAN_CONTINUE_SCENARIO)642return "Why do you like it?"643elif not fact:644state_utils.set_can_continue(vars, continue_flag=CAN_NOT_CONTINUE)645return error_response(vars)646elif fact and entity:647state_utils.set_can_continue(vars, continue_flag=CAN_CONTINUE_SCENARIO)648if len(used_facts):649return f"{fact} Do you want me to tell you more about {entity}?"650else:651response = acknowledgement + f"{fact} Do you want to hear more about {entity}?"652state_utils.add_acknowledgement_to_response_parts(vars)653return response654elif fact:655state_utils.set_can_continue(vars, continue_flag=CAN_CONTINUE_SCENARIO)656if len(used_facts):657return f"{fact} Do you want me to tell you more about {entity}?"658else:659return f"Okay. {fact} I can share with you one more cool fact. Do you agree?"660elif linkto_check:661state_utils.set_confidence(vars, confidence=CONF_MIDDLE)662state_utils.set_can_continue(vars, continue_flag=CAN_CONTINUE_SCENARIO)663return "Sorry. I didn't get what kind of food you have mentioned. Could you repeat it please?"664else:665state_utils.set_can_continue(vars, continue_flag=CAN_NOT_CONTINUE)666return error_response(vars)667except Exception as exc:668logger.exception(exc)669sentry_sdk.capture_exception(exc)670return error_response(vars)671elif linkto_check:672state_utils.set_confidence(vars, confidence=CONF_MIDDLE)673state_utils.set_can_continue(vars, continue_flag=CAN_CONTINUE_SCENARIO)674return "Sorry. I didn't get what kind of food you have mentioned. Could you repeat it please?"675else:676state_utils.set_can_continue(vars, continue_flag=CAN_NOT_CONTINUE)677return error_response(vars)678
679
680def more_facts_request(ngrams, vars):681shared_memory = state_utils.get_shared_memory(vars)682used_facts = shared_memory.get("used_facts", [])683
684flag = all([bool(len(used_facts)), condition_utils.no_special_switch_off_requests(vars), yes_request(ngrams, vars)])685logger.info(f"more_facts_request {flag}")686return flag687
688
689def are_you_gourmet_response(vars):690try:691state_utils.set_confidence(vars, confidence=CONF_MIDDLE)692state_utils.set_can_continue(vars, continue_flag=CAN_CONTINUE_SCENARIO)693return "Are you a gourmet?"694except Exception as exc:695logger.exception(exc)696sentry_sdk.capture_exception(exc)697return error_response(vars)698
699
700##################################################################################################################
701# what to cook
702##################################################################################################################
703
704
705def what_cook_request(ngrams, vars):706what_cook_re_search = re.search(WHAT_COOK_RE, state_utils.get_last_human_utterance(vars)["text"])707flag = bool(what_cook_re_search)708logger.info(f"what_cook_request {flag}")709return flag710
711
712def how_about_meal_response(vars):713shared_memory = state_utils.get_shared_memory(vars)714used_meals = shared_memory.get("used_meals", "")715meal = random.choice([i for i in MEALS if i != used_meals])716try:717state_utils.set_confidence(vars, confidence=CONF_HIGH)718state_utils.set_can_continue(vars, continue_flag=MUST_CONTINUE)719# first attempt to suggest a meal720state_utils.save_to_shared_memory(vars, used_meals=meal)721if not used_meals:722return f"I've recently found a couple easy and healthy meals. How about cooking {meal}?"723else:724return f"Okay. Give me one more chance. I recommend {meal}."725except Exception as exc:726logger.exception(exc)727sentry_sdk.capture_exception(exc)728return error_response(vars)729
730
731def recipe_response(vars):732try:733shared_memory = state_utils.get_shared_memory(vars)734used_meal = shared_memory.get("used_meals", "")735recipe = get_fact(used_meal, f"how to cook {used_meal}")736state_utils.set_confidence(vars, confidence=CONF_HIGH)737if not (used_meal and recipe):738state_utils.set_can_continue(vars, continue_flag=CAN_NOT_CONTINUE)739recipe = "Great! Enjoy your meal!"740else:741state_utils.set_can_continue(vars, continue_flag=CAN_CONTINUE_PROMPT)742return recipe743except Exception as exc:744logger.exception(exc)745sentry_sdk.capture_exception(exc)746return error_response(vars)747
748
749def gourmet_response(vars):750try:751state_utils.set_confidence(vars, confidence=CONF_MIDDLE)752state_utils.set_can_continue(vars, continue_flag=CAN_CONTINUE_PROMPT)753response = "It seems you're a gourmet! What meal do you like?"754state_utils.add_acknowledgement_to_response_parts(vars)755return response756except Exception as exc:757logger.exception(exc)758sentry_sdk.capture_exception(exc)759return error_response(vars)760
761
762def smth_request(ngrams, vars):763flag = condition_utils.no_requests(vars) and (not dont_want_talk(vars))764logger.info(f"smth_request {flag}")765return flag766
767
768def smth_random_request(ngrams, vars):769flag = condition_utils.no_requests(vars)770flag = flag and random.choice([True, False])771logger.info(f"smth_random_request {flag}")772return flag773
774
775def where_are_you_from_response(vars):776try:777state_utils.set_confidence(vars, confidence=CONF_LOW)778state_utils.set_can_continue(vars, continue_flag=CAN_NOT_CONTINUE)779return "Where are you from?"780except Exception as exc:781logger.exception(exc)782sentry_sdk.capture_exception(exc)783return error_response(vars)784
785
786def suggest_cook_response(vars):787user_utt = state_utils.get_last_human_utterance(vars)788try:789linkto_food_skill_agreed = any(790[req.lower() in state_utils.get_last_bot_utterance(vars)["text"].lower() for req in TRIGGER_PHRASES]791)792if linkto_food_skill_agreed:793if is_yes(user_utt) or bool(re.search(LIKE_RE, user_utt["text"].lower())):794state_utils.set_confidence(vars, confidence=CONF_HIGH)795state_utils.set_can_continue(vars, continue_flag=MUST_CONTINUE)796elif not is_no(user_utt):797state_utils.set_confidence(vars, confidence=CONF_MIDDLE)798state_utils.set_can_continue(vars, continue_flag=CAN_CONTINUE_SCENARIO)799elif is_no(user_utt):800state_utils.set_confidence(vars, confidence=CONF_HIGH)801state_utils.set_can_continue(vars, continue_flag=CAN_NOT_CONTINUE)802return ACKNOWLEDGEMENTS["fav_food_cook"]803else:804state_utils.set_can_continue(vars, continue_flag=CAN_NOT_CONTINUE)805return error_response(vars)806return "May I recommend you a meal to try to practice cooking?"807else:808state_utils.set_can_continue(vars, continue_flag=CAN_NOT_CONTINUE)809return error_response(vars)810except Exception as exc:811logger.exception(exc)812sentry_sdk.capture_exception(exc)813return error_response(vars)814
815
816def what_fav_food_request(ngrams, vars):817food_topic_checked = lets_talk_about_check(vars)818food_1st_time = condition_utils.is_first_time_of_state(vars, State.SYS_WHAT_FAV_FOOD)819cuisine_1st_time = condition_utils.is_first_time_of_state(vars, State.SYS_WHAT_CUISINE)820if any([not bool(food_topic_checked), food_topic_checked == "CUISINE_UTTERANCES_RE", dont_want_talk(vars)]):821flag = False822elif (food_topic_checked == "FOOD_UTTERANCES_RE") or (food_topic_checked == "if_chat_about_particular_topic"):823flag = True824elif food_1st_time and cuisine_1st_time:825flag = random.choice([True, False])826elif food_1st_time or (not cuisine_1st_time):827flag = True828else:829flag = False830logger.info(f"what_fav_food_request {flag}")831return flag832
833
834def check_cooking_request(ngrams, vars):835linkto_food_skill_agreed = any(836[req.lower() in state_utils.get_last_bot_utterance(vars)["text"].lower() for req in TRIGGER_PHRASES]837) and any(838[839is_yes(state_utils.get_last_human_utterance(vars)),840not is_no(state_utils.get_last_human_utterance(vars)),841bool(re.search(LIKE_RE, state_utils.get_last_human_utterance(vars)["text"].lower())),842]843)844if linkto_food_skill_agreed:845flag = True846else:847flag = False848logger.info(f"check_cooking_request {flag}")849return flag850
851
852def said_fav_food_request(ngrams, vars):853flag = False854user_utt_text = state_utils.get_last_human_utterance(vars)["text"]855bot_utt_text = state_utils.get_last_bot_utterance(vars)["text"]856food_topic_checked = lets_talk_about_check(vars)857# fav_in_bot_utt = bool(re.search(FAV_RE, state_utils.get_last_bot_utterance(vars)["text"]))858food_checked = any([bool(re.search(FOOD_WORDS_RE, user_utt_text)), check_conceptnet(vars)[0]])859linkto_check = any([linkto in bot_utt_text for linkto in link_to_skill2i_like_to_talk["dff_food_skill"]])860if any(861[862dont_want_talk(vars),863food_topic_checked == "FOOD_UTTERANCES_RE",864food_topic_checked == "if_chat_about_particular_topic",865]866):867flag = False868# (fav_in_bot_utt and869elif linkto_check or food_checked:870flag = True871else:872flag = False873logger.info(f"said_fav_food_request {flag}")874return flag875
876
877def bot_persona_fav_food_check(vars):878flag = False879if all(880[881"my favorite food is lava cake" in state_utils.get_last_bot_utterance(vars)["text"].lower(),882fav_food_check(vars),883]884):885flag = True886logger.info(f"bot_persona_fav_food_check {flag}")887return flag888
889
890def bot_persona_fav_food_request(ngrams, vars):891flag = bot_persona_fav_food_check(vars)892logger.info(f"bot_persona_fav_food_request {flag}")893return flag894
895
896def what_cuisine_request(ngrams, vars):897linkto_food_skill_agreed = any(898[req.lower() in state_utils.get_last_bot_utterance(vars)["text"].lower() for req in TRIGGER_PHRASES]899) and any(900[is_yes(state_utils.get_last_human_utterance(vars)), not is_no(state_utils.get_last_human_utterance(vars))]901)902flag = (bool(lets_talk_about_check(vars)) or linkto_food_skill_agreed) and (not dont_want_talk(vars))903logger.info(f"what_cuisine_request {flag}")904return flag905
906
907def ensure_food_request(ngrams, vars):908flag = "I didn't get what kind of food have you mentioned" in state_utils.get_last_bot_utterance(vars)["text"]909logger.info(f"ensure_food_request {flag}")910return flag911
912
913def linkto_plus_no_request(ngrams, vars):914bot_utt = state_utils.get_last_bot_utterance(vars)["text"]915flag = any([ackn in bot_utt for ackn in ACKNOWLEDGEMENTS.values()])916flag = flag and condition_utils.no_special_switch_off_requests(vars)917logger.info(f"linkto_plus_no_request {flag}")918return flag919
920
921##################################################################################################################
922##################################################################################################################
923# linking
924##################################################################################################################
925##################################################################################################################
926
927
928##################################################################################################################
929# START
930
931
932simplified_dialogflow.add_user_serial_transitions(933State.USR_START,934{935State.SYS_WHAT_COOK: what_cook_request,936State.SYS_BOT_PERSONA_FAV_FOOD: bot_persona_fav_food_request,937State.SYS_CHECK_COOKING: check_cooking_request,938State.SYS_SAID_FAV_FOOD: said_fav_food_request,939State.SYS_WHAT_FAV_FOOD: what_fav_food_request,940State.SYS_WHAT_CUISINE: what_cuisine_request,941},942)
943simplified_dialogflow.set_error_successor(State.USR_START, State.SYS_ERR)944
945##################################################################################################################
946
947simplified_dialogflow.add_system_transition(State.SYS_SAID_FAV_FOOD, State.USR_FOOD_FACT, food_fact_response)948simplified_dialogflow.set_error_successor(State.SYS_SAID_FAV_FOOD, State.SYS_ERR)949
950
951simplified_dialogflow.add_system_transition(State.SYS_CHECK_COOKING, State.USR_SUGGEST_COOK, suggest_cook_response)952simplified_dialogflow.set_error_successor(State.SYS_CHECK_COOKING, State.SYS_ERR)953
954
955simplified_dialogflow.add_user_serial_transitions(956State.USR_SUGGEST_COOK,957{State.SYS_YES_COOK: yes_request, State.SYS_NO_COOK: no_request, State.SYS_LINKTO_PLUS_NO: linkto_plus_no_request},958)
959simplified_dialogflow.set_error_successor(State.USR_SUGGEST_COOK, State.SYS_ERR)960
961
962simplified_dialogflow.add_system_transition(State.SYS_YES_COOK, State.USR_HOW_ABOUT_MEAL1, how_about_meal_response)963simplified_dialogflow.set_error_successor(State.SYS_YES_COOK, State.SYS_ERR)964
965
966simplified_dialogflow.add_system_transition(State.SYS_NO_COOK, State.USR_WHAT_FAV_FOOD, what_fav_food_response)967simplified_dialogflow.set_error_successor(State.SYS_NO_COOK, State.SYS_ERR)968
969
970simplified_dialogflow.add_system_transition(State.SYS_WHAT_FAV_FOOD, State.USR_WHAT_FAV_FOOD, what_fav_food_response)971simplified_dialogflow.set_error_successor(State.SYS_WHAT_FAV_FOOD, State.SYS_ERR)972
973
974simplified_dialogflow.add_system_transition(State.SYS_BOT_PERSONA_FAV_FOOD, State.USR_FOOD_FACT, food_fact_response)975simplified_dialogflow.set_error_successor(State.SYS_BOT_PERSONA_FAV_FOOD, State.SYS_ERR)976
977
978simplified_dialogflow.add_system_transition(State.SYS_WHAT_CUISINE, State.USR_WHAT_CUISINE, what_cuisine_response)979simplified_dialogflow.set_error_successor(State.SYS_WHAT_CUISINE, State.SYS_ERR)980
981
982simplified_dialogflow.add_user_serial_transitions(983State.USR_WHAT_FAV_FOOD,984{State.SYS_FAV_FOOD: fav_food_request, State.SYS_LINKTO_PLUS_NO_RECIPE: linkto_plus_no_request},985)
986simplified_dialogflow.set_error_successor(State.USR_WHAT_FAV_FOOD, State.SYS_ERR)987
988
989simplified_dialogflow.add_system_transition(990State.SYS_LINKTO_PLUS_NO_RECIPE, State.USR_SUGGEST_COOK, suggest_cook_response991)
992simplified_dialogflow.set_error_successor(State.SYS_LINKTO_PLUS_NO_RECIPE, State.SYS_ERR)993
994
995simplified_dialogflow.add_user_serial_transitions(996State.USR_WHAT_CUISINE,997{State.SYS_CUISINE: cuisine_request, State.SYS_LINKTO_PLUS_NO: linkto_plus_no_request},998)
999simplified_dialogflow.set_error_successor(State.USR_WHAT_CUISINE, State.SYS_ERR)1000
1001
1002simplified_dialogflow.add_system_transition(State.SYS_CUISINE, State.USR_CUISINE_FACT, cuisine_fact_response)1003simplified_dialogflow.set_error_successor(State.SYS_CUISINE, State.SYS_ERR)1004
1005
1006simplified_dialogflow.add_system_transition(State.SYS_LINKTO_PLUS_NO, State.USR_WHAT_FAV_FOOD, what_fav_food_response)1007simplified_dialogflow.set_error_successor(State.SYS_LINKTO_PLUS_NO, State.SYS_ERR)1008
1009
1010simplified_dialogflow.add_user_serial_transitions(1011State.USR_CUISINE_FACT,1012{State.SYS_TO_TRAVEL_SKILL: to_travel_skill_request, State.USR_WHAT_FAV_FOOD: what_fav_food_response},1013)
1014simplified_dialogflow.set_error_successor(State.USR_CUISINE_FACT, State.SYS_ERR)1015
1016
1017simplified_dialogflow.add_system_transition(State.SYS_TO_TRAVEL_SKILL, State.USR_COUNTRY, country_response)1018simplified_dialogflow.set_error_successor(State.SYS_TO_TRAVEL_SKILL, State.SYS_ERR)1019
1020
1021simplified_dialogflow.add_user_transition(State.USR_COUNTRY, State.SYS_SOMETHING, smth_request)1022simplified_dialogflow.set_error_successor(State.USR_COUNTRY, State.SYS_ERR)1023
1024##################################################################################################################
1025# SYS_WHAT_COOK
1026
1027simplified_dialogflow.add_system_transition(State.SYS_WHAT_COOK, State.USR_HOW_ABOUT_MEAL1, how_about_meal_response)1028simplified_dialogflow.set_error_successor(State.SYS_WHAT_COOK, State.SYS_ERR)1029
1030
1031simplified_dialogflow.add_user_serial_transitions(1032State.USR_HOW_ABOUT_MEAL1,1033{1034State.SYS_YES_RECIPE: yes_request,1035State.SYS_NO_RECIPE1: no_request,1036},1037)
1038simplified_dialogflow.set_error_successor(State.USR_HOW_ABOUT_MEAL1, State.SYS_ERR)1039
1040
1041simplified_dialogflow.add_system_transition(State.SYS_YES_RECIPE, State.USR_RECIPE, recipe_response)1042simplified_dialogflow.set_error_successor(State.SYS_YES_RECIPE, State.SYS_ERR)1043
1044
1045simplified_dialogflow.add_user_transition(State.USR_RECIPE, State.SYS_SOMETHING, smth_request)1046simplified_dialogflow.set_error_successor(State.USR_RECIPE, State.SYS_ERR)1047
1048
1049simplified_dialogflow.add_system_transition(State.SYS_NO_RECIPE1, State.USR_HOW_ABOUT_MEAL2, how_about_meal_response)1050simplified_dialogflow.set_error_successor(State.SYS_NO_RECIPE1, State.SYS_ERR)1051
1052
1053simplified_dialogflow.add_user_serial_transitions(1054State.USR_HOW_ABOUT_MEAL2,1055{1056State.SYS_YES_RECIPE: yes_request,1057State.SYS_NO_RECIPE2: no_request,1058},1059)
1060simplified_dialogflow.set_error_successor(State.USR_HOW_ABOUT_MEAL2, State.SYS_ERR)1061
1062
1063simplified_dialogflow.add_system_transition(State.SYS_NO_RECIPE2, State.USR_GOURMET, gourmet_response)1064simplified_dialogflow.set_error_successor(State.SYS_NO_RECIPE2, State.SYS_ERR)1065
1066
1067simplified_dialogflow.add_user_transition(State.USR_GOURMET, State.SYS_FAV_FOOD, fav_food_request)1068simplified_dialogflow.set_error_successor(State.USR_GOURMET, State.SYS_ERR)1069
1070
1071simplified_dialogflow.add_system_transition(State.SYS_FAV_FOOD, State.USR_FOOD_FACT, food_fact_response)1072simplified_dialogflow.set_error_successor(State.SYS_FAV_FOOD, State.SYS_ERR)1073
1074
1075simplified_dialogflow.add_user_serial_transitions(1076State.USR_FOOD_FACT,1077{1078State.SYS_ENSURE_FOOD: ensure_food_request,1079State.SYS_MORE_FACTS: more_facts_request,1080State.SYS_SOMETHING: smth_random_request,1081(scopes.FAST_FOOD, FFState.USR_START): fast_food_request,1082},1083)
1084simplified_dialogflow.set_error_successor(State.USR_FOOD_FACT, State.SYS_ERR)1085
1086
1087simplified_dialogflow.add_system_transition(State.SYS_MORE_FACTS, State.USR_FOOD_FACT, food_fact_response)1088simplified_dialogflow.set_error_successor(State.SYS_MORE_FACTS, State.SYS_ERR)1089
1090
1091simplified_dialogflow.add_system_transition(State.SYS_ENSURE_FOOD, State.USR_FOOD_FACT, food_fact_response)1092simplified_dialogflow.set_error_successor(State.SYS_ENSURE_FOOD, State.SYS_ERR)1093
1094
1095simplified_dialogflow.add_system_transition(State.SYS_SOMETHING, State.USR_WHAT_FAV_FOOD, what_fav_food_response)1096simplified_dialogflow.set_error_successor(State.SYS_SOMETHING, State.SYS_ERR)1097
1098#################################################################################################################
1099# SYS_ERR
1100simplified_dialogflow.add_system_transition(1101State.SYS_ERR,1102(scopes.MAIN, scopes.State.USR_ROOT),1103error_response,1104)
1105dialogflow = simplified_dialogflow.get_dialogflow()1106