dream
1747 строк · 69.9 Кб
1# %%
2import os3import logging4import random5from enum import Enum, auto6import re7
8import sentry_sdk9
10from dff import dialogflow_extension11import common.dialogflow_framework.utils.state as state_utils12import common.dialogflow_framework.utils.condition as condition_utils13import common.utils as common_utils14import common.constants as common_constants15import common.news as general_this_news16from common.gossip import talk_about_gossip, skill_trigger_phrases17from common.fact_random import get_fact18
19import dialogflows.scenarios.gossip as this_gossip20import common.gossip as common_gossip21import dialogflows.scenarios.news as this_news22
23import dialogflows.scopes as scopes24
25from dialogflows.flows import utils26
27sentry_sdk.init(dsn=os.getenv("SENTRY_DSN"))28NEWS_API_ANNOTATOR_URL = os.environ.get("NEWS_API_ANNOTATOR_URL")29assert NEWS_API_ANNOTATOR_URL30
31logger = logging.getLogger(__name__)32
33
34class State(Enum):35USR_START = auto()36
37SYS_TOPIC_TO_EVENT = auto()38USR_TOPIC_TO_EVENT = auto()39
40SYS_NO_OR_YES = auto()41USR_NO_OR_YES = auto()42
43SYS_EVENT_TO_PERSON = auto()44USR_EVENT_TO_PERSON = auto()45
46# BEGIN: USR_NOT_INTERESTED_IN_PERSON47SYS_NOT_INTERESTED_IN_PERSON = auto()48USR_NOT_INTERESTED_IN_PERSON = auto()49
50SYS_CHANGE_TO_PERSON = auto()51USR_CHANGE_TO_PERSON = auto()52# transitions back to:53# NOT_INTERESTED_IN_PERSON54# AGREES_ABT_PERSON55# DISAGREES_ABT_PERSON56# SAYS_OPINION_ABT_PERSON57# END58
59# BEGIN: USR_AGREES_ABT_PERSON60SYS_AGREES_ABT_PERSON = auto()61USR_AGREES_ABT_PERSON = auto()62
63SYS_PERSON_AGREE = auto()64USR_PERSON_AGREE = auto()65
66SYS_SAYS_SOMETHING_AFTER_AGREE = auto()67USR_SAYS_SOMETHING_AFTER_AGREE = auto()68# transitions back to:69# NOT_INTERESTED_IN_PERSON70# AGREES_ABT_PERSON71# DISAGREES_ABT_PERSON72# SAYS_OPINION_ABT_PERSON73# END74
75# BEGIN76SYS_DISAGREES_ABT_PERSON = auto()77USR_DISAGREES_ABT_PERSON = auto()78
79SYS_PERSON_DISAGREE = auto()80USR_PERSON_DISAGREE = auto()81
82SYS_SAYS_SOMETHING_AFTER_DISAGREE = auto()83USR_SAYS_SOMETHING_AFTER_DISAGREE = auto()84# transitions back to:85# NOT_INTERESTED_IN_PERSON86# AGREES_ABT_PERSON87# DISAGREES_ABT_PERSON88# SAYS_OPINION_ABT_PERSON89# END90
91# BEGIN: USR_SAYS_OPINION_ABT_PERSON92SYS_SAYS_OPINION_ABT_PERSON = auto()93USR_SAYS_OPINION_ABT_PERSON = auto()94
95SYS_PERSON_OPINION = auto()96USR_PERSON_OPINION = auto()97
98SYS_SAYS_SOMETHING_AFTER_OPINION = auto()99USR_SAYS_SOMETHING_AFTER_OPINION = auto()100# transitions back to:101# NOT_INTERESTED_IN_PERSON102# AGREES_ABT_PERSON103# DISAGREES_ABT_PERSON104# SAYS_OPINION_ABT_PERSON105# END106
107SYS_MENTIONS_ANOTHER_PERSON = auto()108USR_MENTIONS_ANOTHER_PERSON = auto()109
110# Helpers: Error111SYS_ERR = auto()112USR_ERR = auto()113
114# Helpers: End?115SYS_END = auto()116USR_END = auto()117
118
119# endregion
120
121
122# region CONFIDENCES
123DIALOG_BEGINNING_START_CONFIDENCE = 0.98124DIALOG_BEGINNING_CONTINUE_CONFIDENCE = 0.9125DIALOG_BEGINNING_SHORT_ANSWER_CONFIDENCE = 0.98126MIDDLE_DIALOG_START_CONFIDENCE = 0.7127SUPER_CONFIDENCE = 1.0128HIGH_CONFIDENCE = 0.98129
130MUST_CONTINUE_CONFIDENCE = 0.98131CANNOT_CONTINUE_CONFIDENCE = 0.0132# endregion
133
134# endregion
135
136################################################################################
137# %%
138
139
140##################################################################################################################
141# Init DialogFlow
142##################################################################################################################
143
144
145simplified_dialogflow = dialogflow_extension.DFEasyFilling(State.USR_START)146
147
148##################################################################################################################
149##################################################################################################################
150# Design DialogFlow.
151##################################################################################################################
152##################################################################################################################
153##################################################################################################################
154# utils
155
156
157def get_people_for_topic(cobot_topic):158# human-curated list (top 10-20 for 2010s)159peoples = [160list(x.get("People", [])) for x in common_gossip.TOPICS_TO_PEOPLE_MAPPINGS if x.get("Topic", "") == cobot_topic161]162peoples = list(set(sum(peoples, [])))163# wikidata-based list164top_people_from_wiki = utils.get_top_people_from_wiki_for_cobot_topic(cobot_topic, peoples)165return top_people_from_wiki + peoples166
167
168def get_phrase_about_person_in_content(person, content):169# TODO: "." for what?170sentences_list = content.split(".")171
172for sentence in sentences_list:173if sentence.lower().count(person.lower()) > 0:174return sentence175
176
177def save_mentioned_person(vars, person, judgement, share_memory_key):178if person:179shared_memory = state_utils.get_shared_memory(vars)180# "people_mentioned_by_bot"181# obtaining a list of previously mentioned people182all_mentioned_people = shared_memory.get(share_memory_key, [])183are_judgements = [x.get("Judgement", "") == judgement for x in all_mentioned_people]184if sum(are_judgements) == 0:185all_mentioned_people.append({"Judgement": judgement, "People": []})186are_judgements.append(True)187judgement_index = are_judgements.index(True)188people_list = all_mentioned_people[judgement_index]["People"]189is_this_person = people_list and people_list[-1] == person190if not is_this_person:191all_mentioned_people[judgement_index]["People"].append(person)192state_utils.save_to_shared_memory(vars, **{share_memory_key: all_mentioned_people})193
194
195def get_mentioned_people(vars, share_memory_key="", judgements=["Liked", "Disliked", "Not Interested", "Other"]):196shared_memory = state_utils.get_shared_memory(vars)197# obtaining a list of previously mentioned people198all_mentioned_people = shared_memory.get(share_memory_key, [])199if all_mentioned_people:200peoples = [list(x.get("People", [])) for x in all_mentioned_people if x.get("Judgement", "") in judgements]201peoples = list(set(sum(peoples, [])))202return peoples203else:204return []205
206
207# inefficient if number of people is finite
208def get_fresh_person_for_topic(vars, cobot_topic):209all_mentioned_people = set(get_mentioned_people(vars, share_memory_key="people_mentioned_by_bot"))210topic_people = [211list(i.get("People", [])) for i in common_gossip.TOPICS_TO_PEOPLE_MAPPINGS if i.get("Topic", "") == cobot_topic212]213topic_people = sum(topic_people, [])214topic_people = set(topic_people)215topic_people = topic_people - all_mentioned_people216if topic_people:217return random.choice(list(topic_people))218
219
220def mark_news_as_mentioned_by_bot(vars, news_title):221shared_memory = state_utils.get_shared_memory(vars)222
223# obtaining a list of previously mentioned news224all_mentioned_news = shared_memory.get("news_mentioned_by_bot", [])225
226all_mentioned_news.append(news_title)227# saving228state_utils.save_to_shared_memory(vars, all_mentioned_news=all_mentioned_news)229
230
231def get_people_related_to_bot_mentioned_ones(vars, user_mentioned_person):232# for the time being, we support only one user233related_people = []234
235if not user_mentioned_person:236return related_people237
238# user_mentioned_person = user_mentioned_people[0]239
240people_mentioned_and_liked_by_bot = get_mentioned_people(vars, "people_mentioned_by_bot", ["Liked", "Disliked"])241
242for person in people_mentioned_and_liked_by_bot:243relationship = utils.get_relationship_between_two_people(user_mentioned_person, person)244if relationship:245related_people.append([person, relationship])246
247return related_people248
249
250def get_people_related_to_user_mentioned_ones(vars, user_mentioned_person):251# for the time being, we support only one user252related_people = []253
254if not user_mentioned_person:255return related_people256
257# user_mentioned_person = user_mentioned_people[0]258
259people_mentioned_and_liked_by_user = get_mentioned_people(vars, "people_mentioned_by_user", ["Liked", "Disliked"])260
261for person in people_mentioned_and_liked_by_user:262relationship = utils.get_relationship_between_two_people(user_mentioned_person, person)263if relationship:264related_people.append([person, relationship])265
266return related_people267
268
269def get_news_for_topic(vars, cobot_topic):270people = get_people_for_topic(cobot_topic)271mentioned_people = get_mentioned_people(vars, share_memory_key="people_mentioned_by_bot")272people = [person for person in people if person not in mentioned_people]273
274if people:275person = random.choice(people)276curr_news = general_this_news.get_news_about_topic(person, NEWS_API_ANNOTATOR_URL)277logger.debug(f"news = {curr_news}")278
279if curr_news and "content" in curr_news and "title" in curr_news:280content = curr_news["content"].split("[")[0]281title = curr_news["title"]282
283if person.lower() in content.lower():284logger.debug("random_person was mentioned in content")285filtered_content = get_phrase_about_person_in_content(person.lower(), content.lower())286return person, title, filtered_content287elif person.lower() in title.lower():288logger.debug("random_person was mentioned in title")289return person, title, content290
291topic_news = [292list(i["News"]) for i in this_news.TEMPORARY_NEWS_FOR_COBOT_TOPICS if i.get("Topic", "") == cobot_topic293]294topic_news = sum(topic_news, [])295logger.debug(f"topic_news={topic_news}")296if topic_news:297random_news = random.choice(topic_news)298person = random_news["Person"]299title = random_news["Title"]300content = random_news["Content"]301else:302person = ""303title = ""304content = ""305
306return person, title, content307
308
309def get_random_judgement_for_emotion(emotion):310judgements = [311list(x.get("People", [])) for x in this_gossip.TARGET_JUDGEMENTS_FOR_EMOTION if x["Emotion"] in emotion312]313judgements = list(set(sum(judgements, [])))314return random.choice(judgements) if judgements else "Great"315
316
317supported_cobot_topics = [318"Entertainment_Movies",319"Entertainment_Music",320"Entertainment_Books",321"Sports",322"Politics",323"Entertainment_General",324"Science_and_Technology",325]
326
327
328def get_supported_cobot_topics(vars):329topics = common_utils.get_topics(state_utils.get_last_human_utterance(vars), which="cobot_dialogact_topics")330selected_topics = set(topics) & set(supported_cobot_topics)331selected_topics = selected_topics if selected_topics else supported_cobot_topics332return selected_topics333
334
335##################################################################################################################
336# error
337##################################################################################################################
338
339
340def error_response(vars):341logger.debug("exec error_response")342state_utils.set_confidence(vars, CANNOT_CONTINUE_CONFIDENCE)343state_utils.set_confidence(vars, 0)344return ""345
346
347##################################################################################################################
348# Handlers
349##################################################################################################################
350
351
352def talk_about_gossip_request(ngrams, vars):353human_utterance = state_utils.get_last_human_utterance(vars)354bot_utterance = state_utils.get_last_bot_utterance(vars)355flag = talk_about_gossip(human_utterance, bot_utterance)356logger.info(f"talk_about_gossip_request: {flag}")357return flag358
359
360# region CELEBRITY
361##################################################################################################################
362
363
364def set_people_jobs(vars, celebrity_name, core_jobs, other_jobs, mentioned_jobs):365shared_memory = state_utils.get_shared_memory(vars)366people_jobs = shared_memory.get("people_jobs", {})367mentioned_jobs = people_jobs.get(celebrity_name, {}).get("Mentioned_Jobs", []) + mentioned_jobs368mentioned_jobs = list(set(mentioned_jobs))369people_jobs[celebrity_name] = {"Jobs": core_jobs, "Other_Jobs": other_jobs, "Mentioned_Jobs": mentioned_jobs}370state_utils.save_to_shared_memory(vars, people_jobs=people_jobs)371
372
373def get_people_jobs(vars, celebrity_name):374shared_memory = state_utils.get_shared_memory(vars)375people_jobs = shared_memory.get("people_jobs", {})376celebrity_jobs = people_jobs.get(celebrity_name, {})377argument_names = ["Jobs", "Other_Jobs", "Mentioned_Jobs"]378return [celebrity_jobs.get(argument_name, []) for argument_name in argument_names]379
380
381def get_mentioned_jobs(vars, celebrity_name):382jobs = get_people_jobs(vars, celebrity_name)[-1]383return jobs if jobs else []384
385
386def get_celebrity_from_uttr(vars, exclude_types=False, use_only_last_utt=False):387# Look only at one turn388# shared_memory = state_utils.get_shared_memory(vars)389human_utterance = state_utils.get_last_human_utterance(vars)390logger.debug(f'Calling get_celebrity_from_uttr on {human_utterance["text"]} {exclude_types} {use_only_last_utt}')391
392# we need to get all supported occupations393celebrity_name, matching_types, mismatching_types = common_gossip.celebrity_from_uttr(human_utterance)394logger.warning(f"Relations {celebrity_name} {matching_types} {mismatching_types}")395if not celebrity_name or not matching_types:396return None, None397mentioned_jobs = get_mentioned_jobs(vars, celebrity_name)398mismatching_types = [type_ for type_ in mismatching_types if type_ not in mentioned_jobs]399if exclude_types and mismatching_types:400mentioned_job = random.choice(mismatching_types)401else:402mentioned_job = random.choice(matching_types)403set_people_jobs(vars, celebrity_name, matching_types, mismatching_types, mentioned_jobs + [mentioned_job])404logger.debug(f"Answer for get_celebrity exclude_types {exclude_types} : {celebrity_name} {mentioned_job}")405
406return celebrity_name, mentioned_job407
408
409def sys_celebrity_found_request(ngrams, vars, use_only_last_utt=True):410shared_memory = state_utils.get_shared_memory(vars)411asked_celebrities = shared_memory.get("asked_celebrities", [])412person, occupation = get_celebrity_from_uttr(vars, use_only_last_utt=use_only_last_utt)413flag = person and person not in asked_celebrities414logger.info(f"celebrity_in_phrase_request : {flag}")415return flag416
417
418# get occupations for current_person
419# build phrase about
420def get_celebrity_prompt(vars, person):421logger.debug("Celebrity branch")422shared_memory = state_utils.get_shared_memory(vars)423# persons = get_mentioned_people(vars, share_memory_key="people_mentioned_by_user")424just_was_celebrity_prompt = shared_memory.get("celebrity_prompt", False)425used_celeb_prompts = shared_memory.get("used_celeb_prompts", [])426last_bot_uttr = state_utils.get_last_bot_utterance(vars)["text"]427prompt = None428if person:429# logger.info(f"get_celebrity_prompt for people: {persons}")430# logger.debug(str(persons[-1]))431# person = persons[-1]432logger.info(f"get_celebrity_prompt for person: {person}")433matching_jobs, mismatching_jobs, mentioned_jobs = get_people_jobs(vars, person)434logger.info(f"{person} {matching_jobs} {mismatching_jobs}")435logger.info(f"Mismatching_jobs len {len(mismatching_jobs)}")436if matching_jobs:437logger.info(f"get_celebrity_prompt: matching jobs! just was celebrity prompt? {just_was_celebrity_prompt}")438is_actor = "actor" in " ".join(matching_jobs)439prompt_candidate = (440f"{person} is an amazing {matching_jobs[0]}! " "Would you like to learn more about this person?"441)442we_not_repeat_start_prompt = prompt_candidate not in used_celeb_prompts443actor_asking = "What is your favourite film with this actor?"444if not just_was_celebrity_prompt and matching_jobs and we_not_repeat_start_prompt:445logger.debug("start prompt")446prompt = prompt_candidate447elif just_was_celebrity_prompt and matching_jobs and mismatching_jobs and actor_asking not in last_bot_uttr:448logger.info("get_celebrity_prompt: just was celebrity prompt and actor:")449rand_job = random.choice(mismatching_jobs)450prompt = f"{person} is also a {rand_job}. "451if "actor" in rand_job:452asking = actor_asking453else:454questions = this_gossip.WANT_TO_HEAR_ANOTHER_FACT455asking = random.choice(questions)456prompt = f"{prompt} {asking}"457mismatching_jobs.remove(rand_job)458mentioned_jobs.append(rand_job)459save_mentioned_person(vars, person, "Other", "people_mentioned_by_user")460set_people_jobs(vars, person, matching_jobs, mismatching_jobs, mentioned_jobs)461elif just_was_celebrity_prompt and matching_jobs and actor_asking not in last_bot_uttr:462logger.info("get_celebrity_prompt: just was celebrity prompt and actor:")463prompt = get_cobot_fact(person, used_celeb_prompts)464logger.debug(f"Cobot prompt {prompt}")465elif just_was_celebrity_prompt and not mismatching_jobs and not is_actor:466logger.info("get_celebrity_prompt: just was celebrity prompt and non-actor:")467prompt = get_cobot_fact(person, used_celeb_prompts)468logger.debug(f"Cobot prompt {prompt}")469if prompt:470state_utils.save_to_shared_memory(471vars, celebrity_prompt=True, used_celeb_prompts=used_celeb_prompts + [prompt]472)473return prompt474
475
476# region TOPIC_TO_EVENT
477##################################################################################################################
478
479
480def sys_topic_to_event_request(ngrams, vars):481# we get here because user mentioned a topic, or we've got a topic482# ok so let's for the time being believe that we are here by default - just because a topic was mentioned483bot_utterance = state_utils.get_last_bot_utterance(vars)484flag = (bool(get_supported_cobot_topics(vars)) and talk_about_gossip_request(ngrams, vars)) or (485any([phrase in bot_utterance["text"] for phrase in skill_trigger_phrases()])486and condition_utils.is_yes_vars(vars)487)488logger.info(f"sys_topic_to_event={flag}")489return flag490
491
492def default_condition_request(ngrams, vars):493flag = True494flag = flag and not condition_utils.is_switch_topic(vars)495flag = flag and not condition_utils.is_lets_chat_about_topic_human_initiative(vars)496flag = flag and not condition_utils.is_question(vars)497flag = flag or talk_about_gossip_request(ngrams, vars)498return flag499
500
501def usr_topic_to_event_response(vars):502# %ack%. So, speaking of %target_topic%, this happened recently: %event%. Have you heard about it?503logger.debug("exec usr_topic_to_event_response")504try:505selected_topics = get_supported_cobot_topics(vars)506if selected_topics:507cobot_topic = random.choice(list(selected_topics)) # "Entertainment_Movies" # for the time being508else:509return error_response(vars)510
511# obtaining person, news_title, news_content for a given cobot_topic512person, news_title, news_content = get_news_for_topic(vars, cobot_topic)513logger.debug(f"person = {person}, news_title = {news_title}, news_content = {news_content}, ")514
515person = person.strip()516if person and person.lower() in news_title.lower():517logger.debug(f"News about {person} : {news_title}")518event = news_title519elif person and person.lower() in news_content.lower():520logger.debug(f"News about {person} : It's said that {news_content}: {news_title}")521event = news_content522else:523# for testing purposes only524event = "Natasha Romanoff (Scarlett Johansson) is going back to where it all started"525person = "Scarlett Johansson"526news_title = "Disney will release Scarlett Johansson in Black Widow in theaters and streaming in July"527
528# get ack, body529ack = condition_utils.get_not_used_and_save_sentiment_acknowledgement(vars)530
531# saving person to the list of people mentioned by bot, for now with "Other" judgement532save_mentioned_person(vars, person, "Other", "people_mentioned_by_bot")533# saving news as mentioned by bot534mark_news_as_mentioned_by_bot(vars, news_title)535
536state_utils.save_to_shared_memory(vars, current_person=person)537
538# saving current cobot_topic539state_utils.save_to_shared_memory(vars, current_cobot_topic=cobot_topic)540
541# generating response542
543topic = this_news.COBOT_TO_HUMAN_READABLE_TOPICS.get(cobot_topic)544questions = this_gossip.TOPIC_TO_EVENT_QUESTIONS545questions = questions if topic else [i for i in questions if "target_topic" not in i]546questions = questions if event else [i for i in questions if "target_event" not in i]547
548if not questions:549return error_response(vars)550
551body = random.choice(questions)552
553body = body.replace("target_topic", topic) if topic else body554body = body.replace("target_event", event)555
556# set confidence557state_utils.set_confidence(vars, SUPER_CONFIDENCE)558# can continue = true559state_utils.set_can_continue(vars, common_constants.MUST_CONTINUE)560
561return " ".join([ack, body])562except Exception as exc:563logger.exception(exc)564sentry_sdk.capture_exception(exc)565return error_response(vars)566
567
568# endregion
569
570# region NO_OR_YES
571################################################################################
572
573
574def sys_no_or_yes_request(ngrams, vars):575logger.debug("sys_no_or_yes_request: BEGIN")576flag = False577
578human_utterance = state_utils.get_last_human_utterance(vars)579
580sf_type, sf_confidence = utils.get_speech_function_for_human_utterance(human_utterance)581
582# using speech function classifier for agree (yes)583# (with the aid of MIDAS & Intents for now)584flag = utils.is_speech_function_agree(vars)585
586# using speech function classifier for disagree (no)587if not flag:588flag = utils.is_speech_function_disagree(vars)589flag = flag and default_condition_request(ngrams, vars)590logger.info(f"sys_no_or_yes_request={flag}")591return flag592
593
594def usr_event_to_person_response(vars):595# %ack%. %Person% particularly interested me.596# I %usuality_modulation_level% %Person% is a %complement% %occupation%.597# %Judgement%. But... What do you think?598logger.debug("exec usr_event_to_person_response")599try:600shared_memory = state_utils.get_shared_memory(vars)601
602# obtaining current person603current_person = shared_memory.get("current_person", "")604current_cobot_topic = shared_memory.get("current_cobot_topic", "")605
606# TEMPORARY OVERRIDE607# current_cobot_topic = "Entertainment_Movies"608
609# Positive or Negative610emotion_reaction_options = ["Liked", "Disliked"]611# trusting holy RNG612target_emotion_type = random.choice(emotion_reaction_options)613target_judgement = get_random_judgement_for_emotion(target_emotion_type)614
615# saving current bot's emotion towards the currently discussed person616state_utils.save_to_shared_memory(vars, bot_emotion_towards_current_person=target_emotion_type)617
618# get ack, body619ack = condition_utils.get_not_used_and_save_sentiment_acknowledgement(vars)620
621# generating response622body = random.choice(this_gossip.EVENT_TO_PERSON_QUESTIONS)623
624# putting actual person's name into an upcoming utterance625body = body.replace("target_person", current_person)626body = body.replace("target_judgement", target_judgement)627
628# obtaining occupation (person/generic/wiki-based)629occupation = utils.get_occupation_for_person(current_person, current_cobot_topic, body)630
631logger.info(f"found occupation: {occupation}")632
633# saving it634state_utils.save_to_shared_memory(vars, current_person_occupation=occupation)635
636# further updating body with the obtained occupation637body = body.replace("target_occupation", occupation)638
639# building prompt640prompt = random.choice(this_gossip.AGREEMENT_PROMPTS)641
642state_utils.set_confidence(vars, MUST_CONTINUE_CONFIDENCE)643# can continue = true644state_utils.set_can_continue(vars, common_constants.CAN_CONTINUE_SCENARIO)645
646return " ".join([ack, body, prompt])647except Exception as exc:648logger.exception(exc)649sentry_sdk.capture_exception(exc)650return error_response(vars)651
652
653# endregion
654
655
656# region LOOP #1: NOT_INTERESTED_IN_PERSON
657
658# STEP 1
659################################################################################
660
661
662def get_cobot_fact(celebrity_name, given_facts):663logger.debug(f"Calling cobot_fact for {celebrity_name} {given_facts}")664answer = get_fact(celebrity_name, f"fact about {celebrity_name}")665if answer is None:666error_message = f"Answer from random fact or fact about {celebrity_name} not obtained"667logger.error(error_message)668return None669for phrase_ in ["This might answer your question", "According to Wikipedia"]:670if phrase_ in answer:671answer = answer.split(phrase_)[1]672logger.debug(f"Answer from cobot_fact obtained {answer}")673if answer not in given_facts:674return answer675else:676return ""677
678
679def sys_not_interested_in_person_request(ngrams, vars):680flag = False681human_utterance = state_utils.get_last_human_utterance(vars)682
683sf_type, sf_confidence = utils.get_speech_function_for_human_utterance(human_utterance)684logger.debug(f"sys_not_interested_in_person_request: Speech Function: {sf_type}")685
686# using speech function classifier for not interested687flag = utils.is_not_interested_speech_function(vars)688flag = flag and default_condition_request(ngrams, vars)689
690logger.info(f"sys_not_interested_in_person_request={flag}")691return flag692
693
694def usr_not_interested_in_person_response(vars):695logger.debug("exec usr_not_interested_in_person_response")696try:697shared_memory = state_utils.get_shared_memory(vars)698# obtaining current context699current_cobot_topic = shared_memory.get("current_cobot_topic", "")700# getting human-readable version701# TODO702human_topic = this_news.COBOT_TO_HUMAN_READABLE_TOPICS.get(current_cobot_topic)703
704# obtaining new random person + news for current cobot_topic705person = get_fresh_person_for_topic(vars, current_cobot_topic)706if not person:707raise Exception(f"Have no fresh person for {current_cobot_topic}")708
709# Positive or Negative710emotion_reaction_options = ["Liked", "Disliked"]711# trusting holy RNG712target_emotion_type = random.choice(emotion_reaction_options)713target_judgement = get_random_judgement_for_emotion(target_emotion_type)714
715# saving current bot's emotion towards the currently discussed person716state_utils.save_to_shared_memory(vars, bot_emotion_towards_current_person=target_emotion_type)717
718# saving person to the list of people mentioned by bot, for now with "Other" judgement719save_mentioned_person(vars, person, "Liked", "people_mentioned_by_bot")720# setting current context (only person, we didn't change topic)721state_utils.save_to_shared_memory(vars, current_person=person)722
723# generating response724ack = f"{random.choice(this_gossip.NOT_INTERESTED_IN_PERSON_ACKNOWLEDGEMENTS)}."725prompt = random.choice(this_gossip.CHANGE_TO_OTHER_PERSON_QUESTIONS)726
727# occupation728occupation = utils.get_occupation_for_person(person, current_cobot_topic, prompt)729
730fake_utterance = f"I like to learn more about {occupation} {person} {human_topic}"731gender, age = utils.get_gender_age_person(person, fake_utterance)732
733gender_is = utils.get_human_readable_gender_statement_current_is(gender)734
735prompt = prompt.replace("target_person", person)736prompt = prompt.replace("target_topic", human_topic)737prompt = prompt.replace("target_judgement", target_judgement)738prompt = prompt.replace("target_gender_is", gender_is)739
740# saving it741state_utils.save_to_shared_memory(vars, current_person_occupation=occupation)742
743prompt = prompt.replace("target_occupation", occupation)744
745state_utils.set_confidence(vars, MUST_CONTINUE_CONFIDENCE)746state_utils.set_can_continue(vars, common_constants.CAN_CONTINUE_PROMPT)747
748return " ".join([ack, prompt])749except Exception as exc:750logger.exception(exc)751sentry_sdk.capture_exception(exc)752return error_response(vars)753
754
755# endregion
756
757# region LOOP #2: AGREES_ABT_PERSON
758
759# STEP 1
760################################################################################
761
762
763def sys_agrees_abt_person_request(ngrams, vars):764flag = False765
766human_utterance = state_utils.get_last_human_utterance(vars)767
768sf_type, sf_confidence = utils.get_speech_function_for_human_utterance(human_utterance)769logger.debug(f"sys_agrees_abt_person_request: Speech Function: {sf_type}")770
771# using speech function classifier for agree (yes)772# (with the aid of MIDAS & Intents for now)773flag = utils.is_speech_function_agree(vars)774flag = flag and default_condition_request(ngrams, vars)775
776logger.info(f"sys_agrees_abt_person_request={flag}")777return flag778
779
780patterns_creative_topics = ["Entertainment_Movies", "Entertainment_Books", "Entertainment_Music"]781creative_topics_patterns_re = re.compile("(" + "|".join(patterns_creative_topics) + ")", re.IGNORECASE)782
783
784def replace_occupation(prompt, bot_judgement, current_person_occupation):785if prompt:786prompt = prompt.replace("target_judgement", bot_judgement)787prompt = prompt.replace("target_occupation", current_person_occupation)788return prompt789
790
791def replace_gender(prompt, gender):792if prompt:793is_gender = utils.get_human_readable_gender_statement_current_is(gender)794eir_gender = utils.get_human_readable_gender_statement_current_eir(gender)795im_gender = utils.get_human_readable_gender_statement_current_im(gender)796prompt = prompt.replace("target_gender_is", is_gender)797prompt = prompt.replace("target_gender_im", im_gender)798prompt = prompt.replace("target_gender_eir", eir_gender)799return prompt800
801
802def usr_agrees_abt_person_response(vars):803logger.debug("exec usr_agrees_abt_person_response")804try:805shared_memory = state_utils.get_shared_memory(vars)806
807# obtaining current person's context808
809current_cobot_topic = shared_memory.get("current_cobot_topic", "")810# TODO811human_topic = this_news.COBOT_TO_HUMAN_READABLE_TOPICS.get(current_cobot_topic)812
813current_person = shared_memory.get("current_person", "")814current_person_occupation = shared_memory.get("current_person_occupation", "")815if len(current_person_occupation) == 0:816current_person_occupation = utils.get_basic_occupation_for_topic(current_cobot_topic)817# current_person_occupation = utils.get_occupation_for_person(current_person,818# current_cobot_topic, "I would love to learn more about " + current_person819# + " in " + human_topic)820
821# we need to remember that user agreed with us. Now, the question is, what our emotion was?822bot_emotion_towards_current_person = shared_memory.get("bot_emotion_towards_current_person", "Liked")823# obtaining judgement824bot_judgement = get_random_judgement_for_emotion(bot_emotion_towards_current_person)825
826# obtaining supporting info like gender & age827fake_utterance = f"I like to learn more about {current_person_occupation} {current_person} {human_topic}"828gender, age = utils.get_gender_age_person(current_person, fake_utterance)829
830# obtaining forms831hr_gender = utils.get_human_readable_gender_statement_current_is(gender)832
833# generating generic response834body = "So stick with it!" # YOUR CODE HERE835
836prompt = ""837# TODO : oh my god838notable_work = ""839
840#841logger.debug(f"current cobot topic: {current_cobot_topic}")842
843# we need to generate some opinion based on one of the person's aspects844# ASPECT #1: AGE845age = age[0] if isinstance(age, list) and age else age846try:847age = int(age)848except Exception as exc:849logger.warn(f"Can not cast age: {exc}")850age = 0851if age != 0:852if age < 25:853# mentioning age854body = f"Wow {hr_gender} so young! "855prompt = random.choice(this_gossip.REACTION_TO_YOUNG_AGE[bot_emotion_towards_current_person])856prompt = replace_occupation(prompt, bot_judgement, current_person_occupation)857prompt = replace_gender(prompt, gender)858
859# ASPECT #2: PERSONAL RELATIONSHIPS (SPOUSE/PARTNER)860if not prompt:861spouse, partner = utils.get_spouse_or_partner_person(current_person, fake_utterance)862if spouse is not None and not spouse and partner:863body = ""864prompt = random.choice(this_gossip.ASK_ABOUT_DATING)865prompt = replace_gender(prompt, gender)866
867prompt = prompt.replace("target_partner", partner)868
869# ASPECT #3: CREATIVE WORKS870if not prompt:871is_creative_person = bool(re.search(creative_topics_patterns_re, current_cobot_topic))872# obtaining873if is_creative_person:874item_kind = "notable work"875
876films, songs, albums, notable_works = utils.get_notable_works_for_creative_person(877current_person, fake_utterance878)879
880if "Entertainment_Movies" in current_cobot_topic:881logger.debug(f"movies: {films}")882if films and films[0]:883film = random.choice(films[0])[1]884logger.debug(f"target film: {film}")885notable_work = film if film and film[0] else notable_work886item_kind = "movie"887elif "Entertainment_Music" in current_cobot_topic:888logger.debug(f"albums: {albums}")889if albums and albums[0]:890album = random.choice(albums[0])[1]891logger.debug(f"target album: {album}")892if len(album) > 0:893notable_work = album894item_kind = "album"895elif "Entertainment_Books" in current_cobot_topic:896logger.debug(f"notable works: {notable_works}")897if notable_works and notable_works[0]:898book = random.choice(notable_works[0])[1]899logger.debug(f"target book: {book}")900if len(book) > 0:901notable_work = book902
903item_kind = "book"904
905logger.debug(f"notable_work: {notable_work}")906
907# TODO : oh my god908if notable_work:909# body = "So... "910body = ""911prompt = random.choice(this_gossip.REACTION_TO_CREATIVE_WORK[bot_emotion_towards_current_person])912prompt = prompt.replace("target_creative_work", item_kind)913prompt = prompt.replace("target_work_name", notable_work)914
915prompt = replace_gender(prompt, gender)916prompt = replace_occupation(prompt, bot_judgement, current_person_occupation)917# if user is creative but has no known works we skip `em`918
919# if:920# # body = "So... "921# body = ""922# prompt = random.choice(923# this_gossip.GENERIC_REACTION_TO_CREATIVE_WORK[bot_emotion_towards_current_person]924# )925# prompt = prompt.replace("target_creative_work", item_kind)926
927# ASPECT #4: SPORTSPEOPLE928if not prompt:929if "Sports" in current_cobot_topic:930item_kind = "team"931sports_kind = "sports"932# TODO : oh my god933team_name = "[[]]"934sport, teams = utils.get_teams_for_sportsperson(current_person, fake_utterance)935
936sports_kind = sport[0][1]937
938logger.debug(f"teams: {teams}")939if len(teams) > 0:940random_team = random.choice(teams)941logger.debug(f"target team: {random_team}")942if len(random_team) > 0:943team_name = random_team[1]944
945logger.debug(f"team name: {team_name}")946
947# TODO : oh my god948if "[[]]" not in str(team_name):949# body = "So... "950body = ""951prompt = random.choice(this_gossip.REACTION_TO_SPORT[bot_emotion_towards_current_person])952prompt = prompt.replace("target_sport_name", sports_kind)953prompt = prompt.replace("target_sport_team", team_name)954
955prompt = replace_gender(prompt, gender)956prompt = replace_occupation(prompt, bot_judgement, current_person_occupation)957
958# TODO : oh my god959if "[[]]" in str(team_name):960# body = "So... "961body = ""962prompt = random.choice(this_gossip.GENERIC_REACTION_TO_SPORT[bot_emotion_towards_current_person])963prompt = prompt.replace("target_sport_name", sports_kind)964
965prompt = replace_gender(prompt, gender)966prompt = replace_occupation(prompt, bot_judgement, current_person_occupation)967# ASPECT 5. CELEBRITY968if not prompt:969body = ""970prompt = get_celebrity_prompt(vars, current_person)971logger.info(f"usr_agrees_abt_person_response: CELEBRITY, suggested prompt: {prompt}")972if not prompt:973prompt = ""974else:975im_gender = utils.get_human_readable_gender_statement_current_im(gender)976# eir_gender = utils.get_human_readable_gender_statement_current_eir(gender)977prompt = prompt.replace("this person", im_gender)978prompt = prompt.replace("target_gender_im", im_gender)979
980elif prompt: # put memory to zero981# Not talking about celebrity - saving982logger.debug("Not in celebrity branch")983state_utils.save_to_shared_memory(vars, celebrity_prompt=False)984
985if prompt:986state_utils.set_confidence(vars, MUST_CONTINUE_CONFIDENCE)987state_utils.set_can_continue(vars, common_constants.CAN_CONTINUE_PROMPT)988else:989state_utils.set_confidence(vars, CANNOT_CONTINUE_CONFIDENCE)990state_utils.set_can_continue(vars, common_constants.CAN_NOT_CONTINUE)991
992return " ".join([body, prompt])993except Exception as exc:994logger.exception(exc)995sentry_sdk.capture_exception(exc)996return error_response(vars)997
998
999# # STEP 2
1000# ################################################################################
1001
1002
1003# def sys_person_agree_request(ngrams, vars):
1004# flag = False
1005# raise NotImplementedError() # YOUR CODE HERE
1006# info.info(f"weekend_request={flag}")
1007# return flag
1008
1009
1010# def usr_person_agree_response(vars):
1011# logger.debug("exec usr_person_agree_response")
1012# try:
1013# state_utils.set_confidence(vars, MUST_CONTINUE_CONFIDENCE)
1014# state_utils.set_can_continue(vars)
1015# response_text = "" # YOUR CODE HERE
1016# raise NotImplementedError() # YOUR CODE HERE
1017# return response_text
1018# except Exception as exc:
1019# logger.exception(exc)
1020# sentry_sdk.capture_exception(exc)
1021# return error_response(vars)
1022
1023
1024# # STEP 3
1025# ################################################################################
1026
1027
1028# def sys_says_something_after_agree_request(ngrams, vars):
1029# flag = False
1030# raise NotImplementedError() # YOUR CODE HERE
1031# info.info(f"weekend_request={flag}")
1032# return flag
1033
1034
1035# def usr_says_something_after_agree_response(vars):
1036# logger.debug("exec usr_says_something_after_agree_response")
1037# try:
1038# state_utils.set_confidence(vars, MUST_CONTINUE_CONFIDENCE)
1039# state_utils.set_can_continue(vars)
1040# response_text = "" # YOUR CODE HERE
1041# raise NotImplementedError() # YOUR CODE HERE
1042# return response_text
1043# except Exception as exc:
1044# logger.exception(exc)
1045# sentry_sdk.capture_exception(exc)
1046# return error_response(vars)
1047
1048
1049# endregion
1050
1051# region LOOP #3: DISAGREES_ABT_PERSON
1052
1053# STEP 1
1054################################################################################
1055
1056
1057def sys_disagrees_abt_person_request(ngrams, vars):1058flag = False1059human_utterance = state_utils.get_last_human_utterance(vars)1060
1061sf_type, sf_confidence = utils.get_speech_function_for_human_utterance(human_utterance)1062logger.debug(f"sys_disagrees_abt_person: Speech Function: {sf_type}")1063
1064# using speech function classifier for disagree (no)1065# (with the aid of MIDAS & Intents for now)1066flag = utils.is_speech_function_disagree(vars)1067
1068logger.info(f"sys_disagrees_abt_person={flag}")1069return flag1070
1071
1072def usr_disagrees_abt_person_response(vars):1073logger.debug("exec usr_disagrees_abt_person_response")1074try:1075state_utils.set_confidence(vars, MUST_CONTINUE_CONFIDENCE)1076state_utils.set_can_continue(vars, common_constants.CAN_NOT_CONTINUE)1077# Wait but why... But a little bit smarter this time around1078# response_text = utils.get_not_used_and_save_wait_but_why_question(vars)1079response_text = "OK. I got it."1080return response_text1081except Exception as exc:1082logger.exception(exc)1083sentry_sdk.capture_exception(exc)1084return error_response(vars)1085
1086
1087# # STEP 2
1088# ################################################################################
1089
1090
1091# def sys_person_disagree_request(ngrams, vars):
1092# flag = False
1093# raise NotImplementedError() # YOUR CODE HERE
1094# info.info(f"weekend_request={flag}")
1095# return flag
1096
1097
1098# def usr_person_disagree_response(vars):
1099# logger.debug("exec usr_person_disagree_response")
1100# try:
1101# state_utils.set_confidence(vars, MUST_CONTINUE_CONFIDENCE)
1102# state_utils.set_can_continue(vars)
1103# response_text = "" # YOUR CODE HERE
1104# raise NotImplementedError() # YOUR CODE HERE
1105# return response_text
1106# except Exception as exc:
1107# logger.exception(exc)
1108# sentry_sdk.capture_exception(exc)
1109# return error_response(vars)
1110
1111
1112# # STEP 3
1113# ################################################################################
1114
1115
1116# def sys_says_something_after_disagree_request(ngrams, vars):
1117# flag = False
1118# raise NotImplementedError() # YOUR CODE HERE
1119# info.info(f"weekend_request={flag}")
1120# return flag
1121
1122
1123# def usr_says_something_after_disagree_response(vars):
1124# logger.debug("exec usr_says_something_after_disagree_response")
1125# try:
1126# state_utils.set_confidence(vars, MUST_CONTINUE_CONFIDENCE)
1127# state_utils.set_can_continue(vars)
1128# response_text = "" # YOUR CODE HERE
1129# raise NotImplementedError() # YOUR CODE HERE
1130# return response_text
1131# except Exception as exc:
1132# logger.exception(exc)
1133# sentry_sdk.capture_exception(exc)
1134# return error_response(vars)
1135
1136
1137# endregion
1138
1139# region LOOP #4: SAYS_OPINION_ABT_PERSON
1140
1141# STEP 1
1142################################################################################
1143
1144
1145def sys_says_opinion_abt_person_request(ngrams, vars):1146flag = False1147human_utterance = state_utils.get_last_human_utterance(vars)1148
1149sf_type, sf_confidence = utils.get_speech_function_for_human_utterance(human_utterance)1150logger.debug(f"sys_says_opinion_abt_person_request: Speech Function: {sf_type}")1151
1152# using speech function classifier for express_opinion1153# (with the aid of MIDAS & Intents for now)1154flag = utils.is_speech_function_express_opinion(vars)1155logger.info(f"sys_says_opinion_abt_person_request={flag}")1156return flag1157
1158
1159def usr_says_opinion_abt_person_response(vars):1160logger.debug("exec usr_says_opinion_abt_person_response")1161try:1162shared_memory = state_utils.get_shared_memory(vars)1163
1164# while we understand this is an opinion we don't know what it actually is1165# so we use sentiment analysis as a shortcut1166sentiment = state_utils.get_human_sentiment(vars, negative_threshold=0.75)1167
1168current_person = shared_memory.get("current_person", "")1169
1170# generating sentiment-based response1171
1172sentiment = state_utils.get_human_sentiment(vars, negative_threshold=0.75)1173judgement = "Other"1174if "negative" in sentiment:1175judgement = "Disliked"1176elif "positive" in sentiment:1177judgement = "Liked"1178elif "neutral" in sentiment:1179judgement = "Other"1180
1181save_mentioned_person(vars, current_person, judgement, "people_mentioned_by_user")1182
1183prompt = random.choice(this_gossip.REACTION_TO_USER_OPINION_ABOUT_PERSON[judgement])1184
1185state_utils.set_confidence(vars, MUST_CONTINUE_CONFIDENCE)1186state_utils.set_can_continue(vars, common_constants.CAN_CONTINUE_SCENARIO)1187
1188return prompt1189except Exception as exc:1190logger.exception(exc)1191sentry_sdk.capture_exception(exc)1192return error_response(vars)1193
1194
1195# # STEP 2
1196# ################################################################################
1197
1198
1199# def sys_person_opinion_request(ngrams, vars):
1200# flag = False
1201# raise NotImplementedError() # YOUR CODE HERE
1202# info.info(f"weekend_request={flag}")
1203# return flag
1204
1205
1206# def usr_person_opinion_response(vars):
1207# logger.debug("exec usr_person_opinion_response")
1208# try:
1209# state_utils.set_confidence(vars, MUST_CONTINUE_CONFIDENCE)
1210# state_utils.set_can_continue(vars)
1211# response_text = "" # YOUR CODE HERE
1212# raise NotImplementedError() # YOUR CODE HERE
1213# return response_text
1214# except Exception as exc:
1215# logger.exception(exc)
1216# sentry_sdk.capture_exception(exc)
1217# return error_response(vars)
1218
1219
1220# # STEP 3
1221# ################################################################################
1222
1223
1224# def sys_says_something_after_opinion_request(ngrams, vars):
1225# flag = False
1226# raise NotImplementedError() # YOUR CODE HERE
1227# info.info(f"weekend_request={flag}")
1228# return flag
1229
1230
1231# def usr_says_something_after_opinion_response(vars):
1232# logger.debug("exec usr_says_something_after_opinion_response")
1233# try:
1234# state_utils.set_confidence(vars, MUST_CONTINUE_CONFIDENCE)
1235# state_utils.set_can_continue(vars)
1236# response_text = "" # YOUR CODE HERE
1237# raise NotImplementedError() # YOUR CODE HERE
1238# return response_text
1239# except Exception as exc:
1240# logger.exception(exc)
1241# sentry_sdk.capture_exception(exc)
1242# return error_response(vars)
1243
1244
1245# endregion
1246
1247# # region SYS_CHANGE_TO_PERSON
1248# ################################################################################
1249
1250
1251# def sys_change_to_person_request(ngrams, vars):
1252# flag = True
1253# # raise NotImplementedError() # YOUR CODE HERE
1254# info.info(f"sys_change_to_person_request={flag}")
1255# return flag
1256
1257
1258def usr_change_to_person_response(vars):1259logger.debug("exec usr_not_interested_in_person_response")1260try:1261shared_memory = state_utils.get_shared_memory(vars)1262# obtaining current context1263current_cobot_topic = shared_memory.get("current_cobot_topic", "")1264# getting human-readable version1265human_topic = this_news.COBOT_TO_HUMAN_READABLE_TOPICS.get(current_cobot_topic)1266
1267# obtaining new random person + news for current cobot_topic1268person = get_fresh_person_for_topic(vars, current_cobot_topic)1269
1270# Positive1271target_emotion_type = "Liked"1272target_judgement = get_random_judgement_for_emotion(target_emotion_type)1273
1274# saving current bot's emotion towards the currently discussed person1275state_utils.save_to_shared_memory(vars, bot_emotion_towards_current_person=target_emotion_type)1276
1277# saving person to the list of people mentioned by bot, for now with "Other" judgement1278save_mentioned_person(vars, person, "Liked", "people_mentioned_by_bot")1279# setting current context (only person, we didn't change topic)1280state_utils.save_to_shared_memory(vars, current_person=person)1281
1282# generating response1283ack = condition_utils.get_not_used_and_save_sentiment_acknowledgement(vars)1284
1285prompt = random.choice(this_gossip.CHANGE_TO_OTHER_PERSON_QUESTIONS)1286
1287prompt = prompt.replace("target_person", person) if person else prompt1288prompt = prompt.replace("target_topic", human_topic) if human_topic else prompt1289prompt = prompt.replace("target_judgement", target_judgement)1290
1291# occupation1292occupation = utils.get_occupation_for_person(person, current_cobot_topic, prompt)1293
1294prompt = prompt.replace("target_occupation", occupation)1295
1296state_utils.set_confidence(vars, MUST_CONTINUE_CONFIDENCE)1297state_utils.set_can_continue(vars, common_constants.CAN_CONTINUE_PROMPT)1298return " ".join([ack, prompt])1299except Exception as exc:1300logger.exception(exc)1301sentry_sdk.capture_exception(exc)1302return error_response(vars)1303
1304
1305# STEP 2 MENTIONS_ANOTHER_PERSON
1306################################################################################
1307
1308
1309def sys_mentions_another_person_request(ngrams, vars):1310flag = False1311
1312use_only_last_utt = True1313mentioned_by_user_people = []1314found_celebrity, _ = get_celebrity_from_uttr(vars, use_only_last_utt=use_only_last_utt)1315
1316if found_celebrity:1317mentioned_by_user_people.append(found_celebrity)1318
1319logger.info(f"sys_mentions_another_person_request: {mentioned_by_user_people}")1320
1321shared_memory = state_utils.get_shared_memory(vars)1322current_person = shared_memory.get("current_person", "")1323current_person = str(current_person)1324
1325logger.debug(f"mentioned_people: {mentioned_by_user_people}")1326other_mentioned_people = [1327people for people in mentioned_by_user_people if str(people).lower() != current_person.lower()1328]1329
1330# checking if user mentioned at least one person1331if len(other_mentioned_people) > 0:1332flag = True1333
1334logger.info(f"sys_mentions_another_person_request={flag}")1335return flag1336
1337
1338def usr_mentions_another_person_response(vars):1339logger.debug("exec usr_mentions_another_person_response")1340try:1341shared_memory = state_utils.get_shared_memory(vars)1342
1343# sf_type, sf_confidence = utils.get_speech_function_for_human_utterance(human_utterance)1344# logger.debug(f"usr_mentions_another_person_response: Speech Function: {sf_type}")1345
1346# using speech function classifier for express_opinion1347# (with the aid of MIDAS & Intents for now)1348
1349use_only_last_utt = True1350found_celebrity, occupation = get_celebrity_from_uttr(vars, use_only_last_utt=use_only_last_utt)1351
1352# obtaining occupation (person/generic/wiki-based)1353# occupation = utils.get_occupation_for_person(current_person, current_cobot_topic, body)1354
1355logger.info(f"found occupation: {occupation}")1356
1357# saving it1358state_utils.save_to_shared_memory(vars, current_person_occupation=occupation)1359
1360if found_celebrity:1361logger.info(f"user just mentioned these people: {found_celebrity}")1362
1363# obtaining previously mentioned people1364# user_mentioned_people = get_mentioned_people(vars, share_memory_key="people_mentioned_by_user")1365
1366# checking current person1367current_person = shared_memory.get("current_person", "")1368
1369body = random.choice(this_gossip.CONFUSED_WHY_USER_MENTIONED_PEOPLE)1370state_utils.set_confidence(vars, DIALOG_BEGINNING_CONTINUE_CONFIDENCE)1371state_utils.set_can_continue(vars, common_constants.CAN_CONTINUE_PROMPT)1372# checking if user mentioned at least one person1373if found_celebrity:1374state_utils.set_confidence(vars, MUST_CONTINUE_CONFIDENCE)1375state_utils.set_can_continue(vars, common_constants.CAN_CONTINUE_PROMPT)1376user_mentioned_person = found_celebrity1377logger.info("# of mentioned people: 1")1378# path #1: mentioned person is the current one (w/o coref)1379if str(user_mentioned_person).lower() in str(current_person).lower():1380logger.info(f"just mentioned person {user_mentioned_person} is the current_one: {current_person}")1381if utils.is_speech_function_demand_opinion(vars):1382if current_person in get_mentioned_people(vars, "people_mentioned_by_bot", ["Liked"]):1383body = random.choice(this_gossip.SIMPLE_OPINION_ABOUT_LIKED_PERSON_PREVIOUSLY_MENTIONED_BY_BOT)1384fake_utterance = f"I like to learn more about {user_mentioned_person}"1385gender, age = utils.get_gender_age_person(user_mentioned_person, fake_utterance)1386gender_is = utils.get_human_readable_gender_statement_current_is(gender)1387body = body.replace("target_gender_is", gender_is)1388elif current_person in get_mentioned_people(vars, "people_mentioned_by_bot", ["Disliked"]):1389body = random.choice(1390this_gossip.SIMPLE_OPINION_ABOUT_DISLIKED_PERSON_PREVIOUSLY_MENTIONED_BY_BOT1391)1392fake_utterance = f"I like to learn more about {user_mentioned_person}"1393gender, age = utils.get_gender_age_person(user_mentioned_person, fake_utterance)1394gender_is = utils.get_human_readable_gender_statement_current_is(gender)1395body = body.replace("target_gender_is", gender_is)1396if utils.is_speech_function_express_opinion(vars):1397body = random.choice(this_gossip.SIMPLE_REACTION_TO_PERSON_PREVIOUSLY_MENTIONED_BY_BOT)1398# path #2: mentioned person is the one mentioned by bot before1399elif user_mentioned_person in get_mentioned_people(vars, share_memory_key="people_mentioned_by_bot"):1400if utils.is_speech_function_demand_opinion(vars):1401if user_mentioned_person in get_mentioned_people(vars, "people_mentioned_by_bot", ["Liked"]):1402body = random.choice(this_gossip.SIMPLE_OPINION_ABOUT_LIKED_PERSON_PREVIOUSLY_MENTIONED_BY_BOT)1403fake_utterance = f"I like to learn more about {user_mentioned_person}"1404gender, age = utils.get_gender_age_person(user_mentioned_person, fake_utterance)1405gender_is = utils.get_human_readable_gender_statement_current_is(gender)1406body = body.replace("target_gender_is", gender_is)1407elif user_mentioned_person in get_mentioned_people(vars, "people_mentioned_by_bot", ["Disliked"]):1408body = random.choice(1409this_gossip.SIMPLE_OPINION_ABOUT_DISLIKED_PERSON_PREVIOUSLY_MENTIONED_BY_BOT1410)1411fake_utterance = f"I like to learn more about {user_mentioned_person}"1412gender, age = utils.get_gender_age_person(user_mentioned_person, fake_utterance)1413gender_is = utils.get_human_readable_gender_statement_current_is(gender)1414body = body.replace("target_gender_is", gender_is)1415if utils.is_speech_function_express_opinion(vars):1416body = random.choice(this_gossip.SIMPLE_REACTION_TO_PERSON_PREVIOUSLY_MENTIONED_BY_BOT)1417# path #3: mentioned person is the one mentioned by user before1418elif user_mentioned_person in get_mentioned_people(vars, "people_mentioned_by_user"):1419if utils.is_speech_function_demand_opinion(vars):1420body = random.choice(this_gossip.SIMPLE_OPINION_ABOUT_PERSON_PREVIOUSLY_MENTIONED_BY_USER)1421if utils.is_speech_function_express_opinion(vars):1422body = random.choice(this_gossip.SIMPLE_REACTION_TO_PERSON_PREVIOUSLY_MENTIONED_BY_USER)1423# path #4: mentioned person is the new one1424else:1425bot_mentioned_people_related_to_new_ones = get_people_related_to_bot_mentioned_ones(1426vars, user_mentioned_person1427)1428user_mentioned_people_related_to_new_ones = get_people_related_to_user_mentioned_ones(1429vars, user_mentioned_person1430)1431# bot mentioned at least one of the people who are related to one user just mentioned1432if len(bot_mentioned_people_related_to_new_ones):1433if utils.is_speech_function_demand_opinion(vars):1434body = random.choice(1435this_gossip.OPINION_TO_USER_MENTIONING_SOMEONE_RELATED_TO_WHO_BOT_MENTIONED_BEFORE1436)1437if utils.is_speech_function_express_opinion(vars):1438body = random.choice(1439this_gossip.REACTION_TO_USER_MENTIONING_SOMEONE_RELATED_TO_WHO_BOT_MENTIONED_BEFORE1440)1441# user mentioned at least one of the people who are related to one user just mentioned1442elif len(user_mentioned_people_related_to_new_ones):1443if utils.is_speech_function_demand_opinion(vars):1444body = random.choice(1445this_gossip.OPINION_TO_USER_MENTIONING_SOMEONE_RELATION_TO_WHO_USER_MENTIONED_BEFORE1446)1447if utils.is_speech_function_express_opinion(vars):1448body = random.choice(1449this_gossip.REACTION_TO_USER_MENTIONING_SOMEONE_RELATED_TO_WHO_USER_MENTIONED_BEFORE1450)1451# we should also think about the same occupation BTW!1452# TO DO1453
1454# generic case, just a new person1455else:1456# being smarter about using templates1457body = utils.get_not_used_and_save_reaction_to_new_mentioned_person(vars)1458fake_utterance = f"I like to learn more about {user_mentioned_person}"1459gender, age = utils.get_gender_age_person(user_mentioned_person, fake_utterance)1460# gender_is = utils.get_human_readable_gender_statement_current_is(gender)1461body = body.replace("target_gender_is", user_mentioned_person + " is ")1462
1463# saving person to the list of people mentioned by bot, for now with "Like" judgement1464save_mentioned_person(vars, current_person, "Liked", "people_mentioned_by_bot")1465
1466# Positive1467target_emotion_type = "Liked"1468# target_judgement = get_random_judgement_for_emotion(target_emotion_type)1469
1470# saving current bot's emotion towards the currently discussed person1471state_utils.save_to_shared_memory(vars, bot_emotion_towards_current_person=target_emotion_type)1472
1473# no matter what we want to save the fact that user mentioned this particular person1474sentiment = state_utils.get_human_sentiment(vars, negative_threshold=0.75)1475judgement = "Other"1476if "negative" in sentiment:1477judgement = "Disliked"1478elif "positive" in sentiment:1479judgement = "Liked"1480elif "neutral" in sentiment:1481judgement = "Liked" # temporary override until we'll get templates for neutral1482
1483save_mentioned_person(vars, user_mentioned_person, judgement, "people_mentioned_by_user")1484
1485# saving current user's emotion towards the currently discussed person1486state_utils.save_to_shared_memory(vars, bot_emotion_towards_current_person=judgement)1487
1488current_person = user_mentioned_person1489# obtaining topic using reverse lookup from occupations1490current_topic = utils.get_cobot_topic_for_occupation(occupation)1491
1492# changing current person and current topic1493state_utils.save_to_shared_memory(vars, current_person=current_person)1494logger.info(f"sys_mentioned_another_person: setting current_person to {current_person}")1495state_utils.save_to_shared_memory(vars, current_cobot_topic=current_topic)1496logger.info(f"sys_mentioned_another_person: setting current_topic to {current_topic}")1497state_utils.save_to_shared_memory(vars, current_person_occupation=occupation)1498logger.info(f"sys_mentioned_another_person: setting current_person_ocupation to {occupation}")1499
1500else:1501logger.info("# of mentioned people: few")1502# finally we are lazy and if we hear more than one person we ask to talk about just one person1503body = random.choice(this_gossip.CONFUSED_WHY_USER_MENTIONED_PEOPLE)1504
1505if body:1506return body1507else:1508return error_response(vars)1509except Exception as exc:1510logger.exception(exc)1511sentry_sdk.capture_exception(exc)1512return error_response(vars)1513
1514
1515# endregion
1516
1517##################################################################################################################
1518# START
1519
1520simplified_dialogflow.add_user_serial_transitions(1521State.USR_START,1522{1523State.SYS_TOPIC_TO_EVENT: sys_topic_to_event_request,1524State.SYS_AGREES_ABT_PERSON: sys_celebrity_found_request,1525# State.SYS_MENTIONS_ANOTHER_PERSON: sys_celebrity_found_request,1526State.SYS_MENTIONS_ANOTHER_PERSON: sys_mentions_another_person_request,1527},1528)
1529simplified_dialogflow.set_error_successor(State.USR_START, State.SYS_ERR)1530
1531# -------------------------------------------------------------------------------
1532# SYS_TOPIC_TO_EVENT
1533
1534simplified_dialogflow.add_system_transition(1535State.SYS_TOPIC_TO_EVENT, State.USR_TOPIC_TO_EVENT, usr_topic_to_event_response1536)
1537
1538simplified_dialogflow.add_user_serial_transitions(1539State.USR_TOPIC_TO_EVENT,1540{1541State.SYS_NO_OR_YES: sys_no_or_yes_request,1542State.SYS_SAYS_OPINION_ABT_PERSON: sys_says_opinion_abt_person_request,1543State.SYS_NOT_INTERESTED_IN_PERSON: sys_not_interested_in_person_request,1544State.SYS_MENTIONS_ANOTHER_PERSON: sys_mentions_another_person_request,1545},1546)
1547
1548simplified_dialogflow.set_error_successor(State.USR_TOPIC_TO_EVENT, State.SYS_ERR)1549
1550# -------------------------------------------------------------------------------
1551# SYS_NO_OR_YES TO SYS_EVENT_TO_PERSON
1552
1553simplified_dialogflow.add_system_transition(1554State.SYS_NO_OR_YES, State.USR_EVENT_TO_PERSON, usr_event_to_person_response1555)
1556
1557simplified_dialogflow.add_user_serial_transitions(1558State.USR_EVENT_TO_PERSON,1559{1560State.SYS_DISAGREES_ABT_PERSON: sys_disagrees_abt_person_request,1561State.SYS_SAYS_OPINION_ABT_PERSON: sys_says_opinion_abt_person_request,1562State.SYS_NOT_INTERESTED_IN_PERSON: sys_not_interested_in_person_request,1563State.SYS_AGREES_ABT_PERSON: sys_agrees_abt_person_request,1564State.SYS_MENTIONS_ANOTHER_PERSON: sys_mentions_another_person_request,1565},1566)
1567
1568simplified_dialogflow.set_error_successor(State.USR_EVENT_TO_PERSON, State.SYS_ERR)1569
1570# region LOOP #1: NOT_INTERESTED_IN_PERSON
1571
1572# -------------------------------------------------------------------------------
1573# SYS_NOT_INTERESTED_IN_PERSON
1574
1575simplified_dialogflow.add_system_transition(1576State.SYS_NOT_INTERESTED_IN_PERSON, State.USR_NOT_INTERESTED_IN_PERSON, usr_not_interested_in_person_response1577)
1578
1579simplified_dialogflow.set_error_successor(State.SYS_NOT_INTERESTED_IN_PERSON, State.SYS_ERR)1580
1581simplified_dialogflow.add_user_serial_transitions(1582State.USR_NOT_INTERESTED_IN_PERSON,1583{1584State.SYS_DISAGREES_ABT_PERSON: sys_disagrees_abt_person_request,1585State.SYS_SAYS_OPINION_ABT_PERSON: sys_says_opinion_abt_person_request,1586State.SYS_NOT_INTERESTED_IN_PERSON: sys_not_interested_in_person_request,1587State.SYS_AGREES_ABT_PERSON: sys_agrees_abt_person_request,1588State.SYS_MENTIONS_ANOTHER_PERSON: sys_mentions_another_person_request,1589},1590)
1591
1592# simplified_dialogflow.add_user_transition(
1593# State.USR_NOT_INTERESTED_IN_PERSON,
1594# State.SYS_CHANGE_TO_PERSON,
1595# sys_change_to_person_request)
1596
1597# workaround
1598simplified_dialogflow.set_error_successor(State.USR_NOT_INTERESTED_IN_PERSON, State.SYS_CHANGE_TO_PERSON)1599
1600# endregion
1601
1602# region LOOP #2: AGREES_ABT_PERSON
1603
1604# -------------------------------------------------------------------------------
1605# SYS_AGREES_ABT_PERSON
1606
1607simplified_dialogflow.add_system_transition(1608State.SYS_AGREES_ABT_PERSON, State.USR_AGREES_ABT_PERSON, usr_agrees_abt_person_response1609)
1610
1611simplified_dialogflow.add_user_serial_transitions(1612State.USR_AGREES_ABT_PERSON,1613{1614State.SYS_DISAGREES_ABT_PERSON: sys_disagrees_abt_person_request,1615State.SYS_SAYS_OPINION_ABT_PERSON: sys_says_opinion_abt_person_request,1616State.SYS_NOT_INTERESTED_IN_PERSON: sys_not_interested_in_person_request,1617State.SYS_AGREES_ABT_PERSON: sys_agrees_abt_person_request,1618State.SYS_MENTIONS_ANOTHER_PERSON: sys_mentions_another_person_request,1619},1620)
1621
1622# simplified_dialogflow.add_user_transition(
1623# State.USR_AGREES_ABT_PERSON,
1624# # State.SYS_PERSON_AGREE,
1625# # sys_person_agree_request)
1626# State.SYS_CHANGE_TO_PERSON,
1627# sys_change_to_person_request)
1628
1629# workaround
1630simplified_dialogflow.set_error_successor(State.USR_AGREES_ABT_PERSON, State.SYS_CHANGE_TO_PERSON)1631
1632# endregion
1633
1634# region LOOP #3: DISAGREES_ABT_PERSON
1635
1636# -------------------------------------------------------------------------------
1637# SYS_DISAGREES_ABT_PERSON
1638
1639simplified_dialogflow.add_system_transition(1640State.SYS_DISAGREES_ABT_PERSON, State.USR_DISAGREES_ABT_PERSON, usr_disagrees_abt_person_response1641)
1642
1643simplified_dialogflow.set_error_successor(State.SYS_DISAGREES_ABT_PERSON, State.SYS_ERR)1644
1645# simplified_dialogflow.add_user_serial_transitions(
1646# State.USR_DISAGREES_ABT_PERSON,
1647# {
1648# State.SYS_MENTIONS_ANOTHER_PERSON: sys_mentions_another_person_request,
1649# State.SYS_DISAGREES_ABT_PERSON: sys_disagrees_abt_person_request,
1650# State.SYS_SAYS_OPINION_ABT_PERSON: sys_says_opinion_abt_person_request,
1651# State.SYS_NOT_INTERESTED_IN_PERSON: sys_not_interested_in_person_request,
1652# State.SYS_AGREES_ABT_PERSON: sys_agrees_abt_person_request,
1653# },
1654# )
1655
1656# simplified_dialogflow.add_user_transition(
1657# State.USR_DISAGREES_ABT_PERSON,
1658# # State.SYS_PERSON_DISAGREE,
1659# # sys_person_disagree_request)
1660# State.SYS_CHANGE_TO_PERSON,
1661# sys_change_to_person_request)
1662
1663# workaround
1664simplified_dialogflow.set_error_successor(State.USR_DISAGREES_ABT_PERSON, State.SYS_CHANGE_TO_PERSON)1665
1666# endregion
1667
1668# region LOOP #4: SAYS_OPINION_ABT_PERSON
1669
1670# -------------------------------------------------------------------------------
1671# SYS_SAYS_OPINION_ABT_USER
1672
1673simplified_dialogflow.add_system_transition(1674State.SYS_SAYS_OPINION_ABT_PERSON, State.USR_SAYS_OPINION_ABT_PERSON, usr_says_opinion_abt_person_response1675)
1676
1677simplified_dialogflow.add_user_serial_transitions(1678State.USR_SAYS_OPINION_ABT_PERSON,1679{1680State.SYS_DISAGREES_ABT_PERSON: sys_disagrees_abt_person_request,1681# State.SYS_SAYS_OPINION_ABT_PERSON: sys_says_opinion_abt_person_request,1682State.SYS_NOT_INTERESTED_IN_PERSON: sys_not_interested_in_person_request,1683State.SYS_AGREES_ABT_PERSON: sys_agrees_abt_person_request,1684State.SYS_MENTIONS_ANOTHER_PERSON: sys_mentions_another_person_request,1685},1686)
1687
1688# simplified_dialogflow.add_user_transition(
1689# State.USR_SAYS_OPINION_ABT_PERSON,
1690# # State.SYS_PERSON_OPINION,
1691# State.SYS_CHANGE_TO_PERSON,SYS_DISAGREES_ABT_PERSON
1692# sys_change_to_person_request)
1693
1694# workaround
1695simplified_dialogflow.set_error_successor(State.USR_SAYS_OPINION_ABT_PERSON, State.SYS_CHANGE_TO_PERSON)1696
1697# endregion
1698
1699
1700# -------------------------------------------------------------------------------
1701# SYS_CHANGE_TO_PERSON
1702
1703simplified_dialogflow.add_system_transition(1704State.SYS_CHANGE_TO_PERSON, State.USR_CHANGE_TO_PERSON, usr_change_to_person_response1705)
1706
1707simplified_dialogflow.add_user_serial_transitions(1708State.USR_CHANGE_TO_PERSON,1709{1710State.SYS_DISAGREES_ABT_PERSON: sys_disagrees_abt_person_request,1711State.SYS_SAYS_OPINION_ABT_PERSON: sys_says_opinion_abt_person_request,1712State.SYS_NOT_INTERESTED_IN_PERSON: sys_not_interested_in_person_request,1713State.SYS_AGREES_ABT_PERSON: sys_agrees_abt_person_request,1714State.SYS_MENTIONS_ANOTHER_PERSON: sys_mentions_another_person_request,1715},1716)
1717
1718
1719# -------------------------------------------------------------------------------
1720# SYS_MENTIONS_ANOTHER_PERSON
1721
1722simplified_dialogflow.add_system_transition(1723State.SYS_MENTIONS_ANOTHER_PERSON, State.USR_MENTIONS_ANOTHER_PERSON, usr_mentions_another_person_response1724)
1725
1726simplified_dialogflow.add_user_serial_transitions(1727State.USR_MENTIONS_ANOTHER_PERSON,1728{1729State.SYS_DISAGREES_ABT_PERSON: sys_disagrees_abt_person_request,1730State.SYS_SAYS_OPINION_ABT_PERSON: sys_says_opinion_abt_person_request,1731State.SYS_NOT_INTERESTED_IN_PERSON: sys_not_interested_in_person_request,1732State.SYS_AGREES_ABT_PERSON: sys_agrees_abt_person_request,1733State.SYS_MENTIONS_ANOTHER_PERSON: sys_mentions_another_person_request,1734},1735)
1736
1737simplified_dialogflow.set_error_successor(State.USR_CHANGE_TO_PERSON, State.SYS_ERR)1738
1739################################################################################
1740# SYS_ERR
1741simplified_dialogflow.add_system_transition(1742State.SYS_ERR,1743(scopes.MAIN, scopes.State.USR_ROOT),1744error_response,1745)
1746
1747dialogflow = simplified_dialogflow.get_dialogflow()1748