示例#1
0
 def register_dummy_known_person_to_db():
     onto: Ontology = mem.get_ontology()
     sess: Session = mem.get_session()
     person_node = Node(metatype=onto.get_type("Person"))
     person_node.set_properties({'name': 'visionio_test_person'})
     person_node = sess.create(person_node)
     return person_node
示例#2
0
 def delete_dummy_people():
     onto: Ontology = mem.get_ontology()
     sess: Session = mem.get_session()
     person_node = Node(metatype=onto.get_type("Person"))
     person_node.set_properties({'name': 'visionio_test_person'})
     # TODO: Delete method is not working!
     sess.delete(person_node)
示例#3
0
 def retrieve_or_create_node(node: Node):
     sess: Session = mem.get_session()
     node_list = sess.retrieve(node)
     if not node_list:
         node = sess.create(node)
     elif len(node_list) > 0:
         node = node_list[0]
     return node
示例#4
0
    def console_input(ctx: ContextWrapper):
        @receptor(ctx_wrap=ctx, write="rawio:in")
        def write_console_input(ctx_input, value: str):
            ctx_input["rawio:in"] = value

        @receptor(ctx_wrap=ctx, write="interloc:all")
        def push_console_interloc(ctx: ContextWrapper, console_node: Node):
            if ctx.push(parentpath="interloc:all",
                        child=PropertyBase(name=DEFAULT_INTERLOC_ID,
                                           default_value=console_node)):
                logger.debug(f"Pushed {console_node} to interloc:all")

        @receptor(ctx_wrap=ctx, write="interloc:all")
        def pop_console_interloc(ctx: ContextWrapper):
            if ctx.pop(f"interloc:all:{DEFAULT_INTERLOC_ID}"):
                logger.debug(f"Popped interloc:all:{DEFAULT_INTERLOC_ID}")

        while not ctx.shutting_down():
            input_value = input("> ")
            write_console_input(input_value)

            console_interloc_exists = f"interloc:all:{DEFAULT_INTERLOC_ID}" in ctx.enum(
                "interloc:all")
            # push Node if you got a greeting
            if input_value.strip() in get_phrase_list(
                    "greeting") and not console_interloc_exists:
                # set up scientio
                sess: Session = ravestate_ontology.get_session()
                onto: Ontology = ravestate_ontology.get_ontology()

                # create scientio Node of type Person
                query = Node(metatype=onto.get_type("Person"))
                query.set_name("x")
                console_node_list = sess.retrieve(query)
                if not console_node_list:
                    console_node = sess.create(query)
                    logger.info(
                        f"Created new Node in scientio session: {console_node}"
                    )
                elif len(console_node_list) == 1:
                    console_node = console_node_list[0]
                else:
                    logger.error(
                        f'Found multiple Persons with name {DEFAULT_INTERLOC_ID} in scientio session. Cannot push node to interloc:all!'
                    )
                    continue

                # push interloc-Node
                push_console_interloc(console_node)

            # pop Node if you got a farewell
            elif input_value.strip() in get_phrase_list(
                    "farewells") and console_interloc_exists:
                pop_console_interloc()
示例#5
0
 def fup_react(ctx: rs.ContextWrapper):
     sess: Session = mem.get_session()
     subject_node: Node = ctx[interloc_path]
     pred = ctx[prop_predicate]
     object_node_list = []
     relationship_ids: Set[int] = subject_node.get_relationships(pred)
     if len(relationship_ids) > 0:
         object_node_list = sess.retrieve(
             node_id=list(relationship_ids)[0])
     if len(object_node_list) > 0:
         ctx[rawio.prop_out] = verbaliser.get_random_followup_answer(
             pred).format(name=subject_node.get_name(),
                          obj=object_node_list[0].get_name())
     else:
         ctx[rawio.prop_out] = "Oh, I see!"
     ctx[prop_predicate] = None
示例#6
0
        def small_talk(ctx: rs.ContextWrapper):
            sess: Session = mem.get_session()
            interloc: Node = ctx[interloc_path]

            if interloc.get_id(
            ) < 0:  # ask for name, if the interlocutor is not (yet) a persistent instance
                pred = "NAME"
            else:
                pred = find_empty_relationship(interloc.get_relationships())
            ctx[prop_subject] = interloc_path
            if not ctx[prop_predicate]:
                if pred:
                    logger.info(f"Personal question: intent={pred}")
                    ctx[prop_predicate] = pred
                    ctx[rawio.prop_out] = verbaliser.get_random_question(pred)
                else:
                    unused_fup_preds = PREDICATE_SET.difference(
                        used_follow_up_preds)
                    if not unused_fup_preds:
                        logger.info(
                            f"Ran out of smalltalk predicates for {interloc_path}, committing suicide..."
                        )
                        return rs.Delete(resign=True)
                    pred = random.sample(
                        PREDICATE_SET.difference(used_follow_up_preds), 1)
                    pred = pred[0]
                    used_follow_up_preds.add(pred)
                    ctx[prop_predicate] = pred
                    relationship_ids: Set[int] = interloc.get_relationships(
                        pred)
                    if len(relationship_ids) > 0:  # Just to be safe ...
                        object_node_list = sess.retrieve(
                            node_id=list(relationship_ids)[0])
                        if len(object_node_list) > 0:
                            ctx[rawio.
                                prop_out] = verbaliser.get_random_followup_question(
                                    pred).format(
                                        name=interloc.get_name(),
                                        obj=object_node_list[0].get_name())
                            logger.info(f"Follow-up: intent={pred}")
                            return rs.Emit()
                    return rs.Resign()
            else:
                # While the predicate is set, repeat the question. Once the predicate is answered,
                #  it will be set to None, such that a new predicate is entered.
                ctx[rawio.prop_out] = verbaliser.get_random_question(
                    ctx[prop_predicate])
示例#7
0
        def save_person_in_vision(ctx: rs.ContextWrapper):
            """
            Activates if the anonymous interlocutor's name is given and saved to database. Responsible for saving the
            current interlocutor's face vector to redis and setting the current anonymous person in face filter to known
            """

            node: Node = ctx[interloc.prop_persisted]
            encodings = node.get_properties('face_vector')

            face_filter = ctx[prop_face_filter]

            sess: Session = mem.get_session()
            node.set_properties({'face_vector': None})
            sess.update(node)

            face_filter.convert_current_anonymous_to_known(node.get_id())
            save_face(ctx, node.get_id(), encodings)
示例#8
0
    def make_sure_effective_user_exists(update: Update):
        """
        Retrieves scientio Node of User if it exists, otherwise creates it in the scientio session
        Calls the push_telegram_interloc receptor to push the scientio node into interloc:all
        Adds the User to the set of active_users and the chat to the set of active_chats
        """
        active_chats[update.effective_chat.id] = (Timestamp(), None)
        if update.effective_user.id in active_users:
            active_users[update.effective_user.id].add(
                update.effective_chat.id)
        else:
            # set up scientio
            if ontology.initialized.wait():
                sess: Session = ontology.get_session()
                onto: Ontology = ontology.get_ontology()

                # create scientio Node of type TelegramPerson
                query = Node(metatype=onto.get_type("TelegramPerson"))
                prop_dict = {'telegram_id': update.effective_user.id}
                if update.effective_user.username:
                    prop_dict['name'] = update.effective_user.username
                if update.effective_user.full_name:
                    prop_dict['full_name'] = update.effective_user.full_name
                query.set_properties(prop_dict)

                node_list = sess.retrieve(query)
                if not node_list:
                    telegram_node = sess.create(query)
                    logger.info(
                        f"Created new Node in scientio session: {telegram_node}"
                    )
                elif len(node_list) == 1:
                    telegram_node = node_list[0]
                else:
                    logger.error(
                        f'Found multiple TelegramPersons that matched query: {update.message.chat_id} '
                        f'in scientio session. Cannot push node to interloc:all!'
                    )
                    return

                # push chat-Node
                push_telegram_interloc(telegram_node, update.effective_chat.id)
                active_users[update.effective_user.id] = {
                    update.effective_chat.id
                }
示例#9
0
    def store_face_and_name(ctx: rs.ContextWrapper):
        tokens = ctx[nlp.prop_tokens]
        triples = ctx[nlp.prop_triples]
        if len(tokens) == 1:
            name = tokens[0]
        elif triples[0].get_object().text and triples[0].match_either_lemma(
                pred={"be"}):
            name = triples[0].get_object().text
        else:
            ctx["rawio:out"] = "Sorry, what was the name?"
            return rs.Emit()
        ctx["rawio:out"] = f"Got it, I'm sure I'll remember {name} next time I see that face!"

        # Create memory entry
        sess: Session = ravestate_ontology.get_session()
        onto: Ontology = ravestate_ontology.get_ontology()
        query = Node(metatype=onto.get_type("Person"))
        query.set_properties({"name": name})
        node_list = sess.retrieve(query)
        if not node_list:
            node = sess.create(query)
            logger.info(f"Created new Node in scientio session: {node}")
        elif len(node_list) == 1:
            node = node_list[0]
        else:
            logger.error(
                f'Failed to create or retrieve Scientio Node for {name}!')
            return
        logger.info(f"Node ID for {name} in picture is {node.get_id()}!")

        # Store face vector with node id in redis
        try:
            redis_conn = redis.Redis(host=ctx.conf(key=REDIS_HOST_CONF),
                                     port=ctx.conf(key=REDIS_PORT_CONF),
                                     password=ctx.conf(key=REDIS_PASS_CONF))
            redis_conn.set(node.get_id(), ctx["sendpics:face_vec"])
        except redis.exceptions.ConnectionError as e:
            err_msg = "Looks like the redis connection is unavailable :-("
            logger.error(err_msg)
            ctx[rawio.prop_out] = err_msg
示例#10
0
    def react(ctx: rs.ContextWrapper):
        """
        Retrieves memory node with the name, or creates a new one
        outputs a polite response.
        """
        onto: Ontology = mem.get_ontology()
        sess: Session = mem.get_session()
        inferred_answer = ctx[prop_answer]
        pred = ctx[prop_predicate]
        subject_path: str = ctx[prop_subject]
        if not subject_path:
            return rs.Resign()
        subject_node: Node = ctx[subject_path]
        assert inferred_answer

        if pred == "NAME":
            # If name was asked, it must be because the node is not yet persistent
            assert subject_node.get_id() < 0
            subject_node.set_name(inferred_answer)
            persistent_subject_node = retrieve_or_create_node(subject_node)
            # TODO: Workaround - see #83 - if this state would write to interloc:all,
            #  it would promise an interloc:all:pushed signal. This would be
            #  picked up by persqa:new_interloc.
            subject_node.set_node(persistent_subject_node)
            sess.update(subject_node)
            ctx[interloc.prop_persisted] = subject_node
        elif pred in PREDICATE_SET:
            relationship_type = onto.get_type(ONTOLOGY_TYPE_FOR_PRED[pred])
            relationship_node = Node(metatype=relationship_type)
            relationship_node.set_name(inferred_answer)
            relationship_node = retrieve_or_create_node(relationship_node)
            if relationship_node is not None:
                subject_node.add_relationships(
                    {pred: {relationship_node.get_id()}})
                sess.update(subject_node)

        ctx[rawio.prop_out] = verbaliser.get_random_successful_answer(
            pred).format(name=subject_node.get_name(), obj=inferred_answer)
        ctx[prop_predicate] = None
示例#11
0
    def handle_input(bot: Bot, update: Update):
        """
        Handler for incoming messages
        Adds the chat/user of the incoming message to the set of active_chats/active_users
        Calls the telegram_callback receptor to process the incoming message
        Retrieves scientio Node of User if it exists, otherwise creates it in the scientio session
        Calls the push_telegram_interloc receptor to push the scientio node into interloc:all
        """
        telegram_callback(update.effective_message.text)
        active_chats.add(update.effective_chat.id)

        if update.effective_user not in active_users:
            # set up scientio
            sess: Session = ravestate_ontology.get_session()
            onto: Ontology = ravestate_ontology.get_ontology()

            # create scientio Node of type TelegramPerson
            query = Node(metatype=onto.get_type("TelegramPerson"))
            prop_dict = {'telegram_id': update.effective_user.id}
            if update.effective_user.username:
                prop_dict['name'] = update.effective_user.username
            if update.effective_user.full_name:
                prop_dict['full_name'] = update.effective_user.full_name
            query.set_properties(prop_dict)

            node_list = sess.retrieve(query)
            if not node_list:
                telegram_node = sess.create(query)
                logger.info(f"Created new Node in scientio session: {telegram_node}")
            elif len(node_list) == 1:
                telegram_node = node_list[0]
            else:
                logger.error(f'Found multiple TelegramPersons that matched query: {update.message.chat_id} '
                             f'in scientio session. Cannot push node to interloc:all!')
                return

            # push chat-Node
            push_telegram_interloc(telegram_node, update.effective_chat.id)
            active_users.add(update.effective_user)
示例#12
0
    def roboyqa(ctx):
        """
        answers question regarding roboy by retrieving the information out of the neo4j roboy memory graph
        state gets triggered when nlp extracts a new triple: subject, predicate, object
        by analysing the triple the content of the question can be ascertained
        the necessary information is gathered using the neo4j memory session
        if the triple combination is known and the information could be retrieved an answer will be given

        list of questions that can be answered:
        - who are you?
        - what is your name?
        - how old are you?
        - what is your age?
        - what is your hobby?
        - what are your hobbies?
        - what do you like?
        - where are you from?
        - where do you live?
        - who is your father/dad?
        - who is your brother/sibling?
        - who is your friend?
        - what do you want to become?
        - what are you a member of?
        - what can you do?
        - what are your skills?
        - what have you learned?
        - what are your abilities?
        """
        sess: Session = ravestate_ontology.get_session()
        onto: Ontology = ravestate_ontology.get_ontology()

        roboy = Node(metatype=onto.get_type("Robot"))
        roboy.set_properties(ctx.conf(key=ROBOY_NODE_PROP_CONF_KEY))
        node_list = sess.retrieve(request=roboy)
        if node_list:
            roboy = node_list[0]
        else:
            create_default_nodes()
            node_list = sess.retrieve(request=roboy)
            if node_list:
                roboy = node_list[0]
            else:
                logger.error(
                    f"Seems like you do not have my memory running, or no node with properties"
                    f"{ctx.conf(key=ROBOY_NODE_PROP_CONF_KEY)} exists!")
                return rs.Resign()

        triple = ctx[nlp.prop_triples][0]

        category = None
        memory_info = None

        # question word: What?
        if triple.is_question(nlp.QuestionWord.OBJECT):
            if triple.match_either_lemma(pred={"like"}, subj={"hobby"}):
                category = "HAS_HOBBY"
            elif triple.match_either_lemma(pred={"learn"}, subj={"skill"}):
                category = "skills"
            elif triple.match_either_lemma(pred={"can"}, subj={"ability"}):
                category = "abilities"
            elif triple.match_either_lemma(subj={"age"}):
                category = "age"
                memory_info = roboy_age(roboy.get_properties(key="birthdate"))
            elif triple.match_either_lemma(subj={"name"}):
                category = "full_name"
                memory_info = roboy.get_properties(key=category)
            elif triple.match_either_lemma(pred={"become"}):
                category = "future"

        # question word: Where?
        elif triple.is_question(nlp.QuestionWord.PLACE):
            if triple.match_either_lemma(pred={"be"}):
                category = "FROM"
            elif triple.match_either_lemma(pred={"live"}):
                category = "LIVE_IN"

        # question word: Who?
        elif triple.is_question(nlp.QuestionWord.PERSON):
            if triple.match_either_lemma(obj={"father", "dad"}):
                category = "CHILD_OF"
            elif triple.match_either_lemma(obj={"brother", "sibling"}):
                category = "SIBLING_OF"
            elif triple.match_either_lemma(obj={"friend", "girlfriend"}):
                category = "FRIEND_OF"
            else:
                category = "full_name"
                memory_info = roboy.get_properties(key=category)
        elif triple.match_either_lemma(obj={"part", "member"}):
            category = "MEMBER_OF"

        # question word: How?
        elif triple.is_question(nlp.QuestionWord.FORM):
            if triple.match_either_lemma(pred={"old"}):
                category = "age"
                memory_info = roboy_age(roboy.get_properties(key="birthdate"))
            elif triple.match_either_lemma(pred={"be"}):
                category = "well_being"
        elif triple.match_either_lemma(obj={"skill"}):
            category = "skills"
        elif triple.match_either_lemma(obj={"ability"}):
            category = "abilities"

        if category and category.isupper() and not isinstance(
                roboy.get_relationships(key=category), dict):
            node_id = random.sample(roboy.get_relationships(key=category),
                                    1)[0]
            memory_info = sess.retrieve(node_id=int(node_id))[0].get_name()

        elif category and category.islower() and not isinstance(
                roboy.get_properties(key=category), dict):
            property_list = [
                x.strip()
                for x in roboy.get_properties(key=category).split(',')
            ]
            memory_info = random.sample(property_list, 1)[0]

        if memory_info:
            ctx[rawio.prop_out] = verbaliser.get_random_successful_answer(
                "roboy_" + category) % memory_info
        elif category == "well_being":
            ctx[rawio.prop_out] = verbaliser.get_random_successful_answer(
                "roboy_" + category)
        else:
            return rs.Resign()
示例#13
0
def create_default_nodes():
    onto: Ontology = ravestate_ontology.get_ontology()
    sess = ravestate_ontology.get_session()

    organization_type = onto.get_type("Organization")
    city_type = onto.get_type("City")
    person_type = onto.get_type("Person")
    robot_type = onto.get_type("Robot")
    hobby_type = onto.get_type("Hobby")

    student_team_node = Node(metatype=organization_type)
    student_team_node.set_properties({"name": "roboy student team"})

    munich_node = Node(metatype=city_type)
    munich_node.set_properties({"name": "munich"})

    roboy_junior_node = Node(metatype=robot_type)
    roboy_junior_node.set_properties({
        "name":
        "roboy",
        "abilities":
        "talking to people,reading wikipedia,reading reddit",
        "skills":
        "tell jokes,tell fun facts about famous people and places,recognize you next time we meet,"
        "remember your name and our conversation",
        "speed_kmh":
        0,
        "full_name":
        "roboy junior",
        "birthdate":
        "08.03.2013",
        "conversation_id":
        "#bitch_boy",
        "sex":
        "male",
        "age":
        5
    })

    raf_node = Node(metatype=person_type)
    raf_node.set_properties({
        "name": "rafael",
        "full_name": "rafael hostettler"
    })

    lucy_node = Node(metatype=person_type)
    lucy_node.set_properties({"name": "lucy", "age": 6, "sex": "female"})

    reddit_node = Node(metatype=hobby_type)
    reddit_node.set_properties({"name": "reading reddit"})

    roboy_node = Node(metatype=robot_type)
    roboy_node.set_properties({
        "name":
        "roboy two",
        "skills":
        "telling jokes,telling fun facts,telling you about the famous people and places,doing the math",
        "abilities":
        "talk to people,recognize objects,show emotions,move my body,shake a hand,"
        "party like there is no tomorrow,surf the internet,answer your questions",
        "speed_kmh":
        0,
        "birthdate":
        "12.04.2018",
        "full_name":
        "roboy 2.0",
        "conversation_id":
        "#bitch_boy",
        "future":
        "become a robot rights advocate,help people and robots become friends,"
        "find the answer to the question of life the universe and everything,"
        "visit mars and other planets,become a music star,become a michelin star chef,"
        "get a robo pet,become as good as my father",
        "sex":
        "male",
        "age":
        "0"
    })

    tricycle_node = Node(metatype=hobby_type)
    tricycle_node.set_properties({"name": "riding a tricycle"})

    nodes = (student_team_node, munich_node, roboy_junior_node, raf_node,
             lucy_node, reddit_node, roboy_node, tricycle_node)

    for node in nodes:
        sess.create(node)

    roboy_junior_node.add_relationships({"HAS_HOBBY": {reddit_node.get_id()}})
    roboy_junior_node.add_relationships(
        {"MEMBER_OF": {student_team_node.get_id()}})
    roboy_junior_node.add_relationships({"CHILD_OF": {raf_node.get_id()}})
    roboy_junior_node.add_relationships({"LIVE_IN": {munich_node.get_id()}})
    raf_node.add_relationships(
        {"FRIEND_OF": {roboy_node.get_id(),
                       roboy_junior_node.get_id()}})
    raf_node.add_relationships({"WORK_FOR": {student_team_node.get_id()}})
    lucy_node.add_relationships(
        {"FRIEND_OF": {roboy_node.get_id(),
                       roboy_junior_node.get_id()}})
    roboy_node.add_relationships({"FROM": {munich_node.get_id()}})
    roboy_node.add_relationships({"SIBLING_OF": {roboy_junior_node.get_id()}})
    roboy_node.add_relationships(
        {"HAS_HOBBY": {tricycle_node.get_id(),
                       reddit_node.get_id()}})
    roboy_node.add_relationships({"MEMBER_OF": {student_team_node.get_id()}})
    roboy_node.add_relationships({"CHILD_OF": {raf_node.get_id()}})
    roboy_node.add_relationships({"LIVE_IN": {munich_node.get_id()}})

    for node in nodes:
        sess.update(node)
示例#14
0
        def recognize_faces(ctx: rs.ContextWrapper):
            """
            Activates with each incoming face data served by face oracle. Responsible for synchronizing the node of
            person in vision with the anonymous interlocutor node. Uses face oracle filter to organize the incoming data
            and find out the right person.
            """

            face_filter: FaceOracleFilter = ctx[prop_face_filter]
            faces: Faces = ctx[prop_subscribe_faces]

            # Push faces to face filter
            best_guess_changed = face_filter.push_message(faces)
            if best_guess_changed:
                current_best_guess: Person = face_filter.current_best_guess

                onto: Ontology = mem.get_ontology()
                sess: Session = mem.get_session()

                person_node = Node(metatype=onto.get_type("Person"))

                best_guess_id = current_best_guess.id
                face_vector = current_best_guess.face_vector
                if current_best_guess.is_known:

                    person_node_query = sess.retrieve(node_id=best_guess_id)
                    if person_node_query:
                        person_node = person_node_query[0]
                    else:
                        err_msg = "Person with id %s is not found in memory." % best_guess_id
                        logger.error(err_msg)
                        return
                else:
                    person_node.set_properties({
                        'face_vector':
                        face_vector,
                        'name':
                        interloc.ANON_INTERLOC_ID
                    })

                push = False

                # Check if there is any interlocutor. If necessary and pop the current node and push person node
                # instead.
                if any(ctx.enum(interloc.prop_all)):
                    interloc_node: Node = ctx[
                        f'interloc:all:{interloc.ANON_INTERLOC_ID}']

                    # If interloc and the person nodes are not same pop and push person node.
                    if not (interloc_node.get_id() == person_node.get_id()
                            ) or interloc_node.get_id() < 0:
                        # Remove the current interloc
                        logger.info('Popping current interlocutor')
                        popped_node = ctx.pop(
                            f'interloc:all:{interloc.ANON_INTERLOC_ID}')
                        assert popped_node == True
                        push = True
                    else:
                        # Update the face vector of the person already familiar with
                        save_face(ctx, interloc_node.get_id(),
                                  current_best_guess.face_vector)
                else:
                    push = True
                if push:
                    # Push the new interlocutor
                    ctx.push(parent_property_or_path=interloc.prop_all,
                             child=rs.Property(name=interloc.ANON_INTERLOC_ID,
                                               default_value=person_node))
                    logger.info(
                        f"Pushed node with id {person_node.id} to interloc:all"
                    )
示例#15
0
def handle_single_interlocutor_input(ctx: ContextWrapper,
                                     input_value: str,
                                     id="anonymous_interlocutor") -> None:
    """
    Forwards input to `rawio:in` and manages creation/deletion of a singleton
     interlocutor. A new interlocutor node is pushed, when the input is a greeting,
     and there is no interlocutor present. The interlocutor is popped,
     if the input is a farewell, and there is an interlocutor present.

    * `ctx`: Context Wrapper of the calling state. Must have read permissions
     for `interloc:all`.

    * `input_value`: The string input value that should be written to `rawio:in`.

    * `id`: Name of the interlocutor context property, and initial name for
     the interlocutor's Neo4j node (until a proper name is set by persqa).
    """
    @receptor(ctx_wrap=ctx, write="rawio:in")
    def write_input(ctx_input, value: str):
        ctx_input["rawio:in"] = value

    @receptor(ctx_wrap=ctx, write="interloc:all")
    def push_interloc(ctx: ContextWrapper, interlocutor_node: Node):
        if ctx.push(parentpath="interloc:all",
                    child=PropertyBase(name=id,
                                       default_value=interlocutor_node)):
            logger.debug(f"Pushed {interlocutor_node} to interloc:all")

    @receptor(ctx_wrap=ctx, write="interloc:all")
    def pop_interloc(ctx: ContextWrapper):
        if ctx.pop(f"interloc:all:{id}"):
            logger.debug(f"Popped interloc:all:{id}")

    write_input(input_value)

    interloc_exists = f"interloc:all:{id}" in ctx.enum("interloc:all")

    # push Node if you got a greeting
    if input_value.strip() in get_phrase_list(
            "greeting") and not interloc_exists:
        # set up scientio
        sess: Session = ravestate_ontology.get_session()
        onto: Ontology = ravestate_ontology.get_ontology()

        # create scientio Node of type Person
        query = Node(metatype=onto.get_type("Person"))
        query.set_name(id)
        interlocutor_node_list = sess.retrieve(query)
        if not interlocutor_node_list:
            interlocutor_node = sess.create(query)
            logger.info(
                f"Created new Node in scientio session: {interlocutor_node}")
        else:
            interlocutor_node = interlocutor_node_list[0]

        # push interloc-node
        push_interloc(interlocutor_node)

    # pop Node if you got a farewell
    elif input_value.strip() in get_phrase_list(
            "farewells") and interloc_exists:
        pop_interloc()