示例#1
0
def test_unexpected_input_macro():
    df = DialogueFlow("root", initial_speaker=Speaker.USER)
    df.add_user_transition("root", "x", "#UNX")
    df.add_system_transition("x", "y", '"So, whats for dinner?"')
    df.user_turn("blah blah blah blah blah blah")
    tokens = df.system_turn().split()
    assert len(tokens) > 4 and "So, whats for dinner?" == " ".join(tokens[-4:])
示例#2
0
def test_user_transition_list_disjunction():
    df = DialogueFlow("root", initial_speaker=Speaker.USER)
    nlu = ["hello", "hi", "how are you"]
    df.add_user_transition("root", "x", nlu)
    df.update_state_settings("root", error_successor="y")
    df.user_turn("hi")
    assert df.state() == "x"
示例#3
0
def test_unexpected_input_macro():
    df = DialogueFlow('root', initial_speaker=Speaker.USER)
    df.add_user_transition('root', 'x', '#UNX')
    df.add_system_transition('x', 'y', '"So, whats for dinner?"')
    df.user_turn('blah blah blah blah blah blah')
    tokens = df.system_turn().split()
    assert len(tokens) > 4 and 'So, whats for dinner?' == ' '.join(tokens[-4:])
示例#4
0
def test_user_transition_list_disjunction():
    df = DialogueFlow('root', initial_speaker=Speaker.USER)
    nlu = [
        'hello',
        'hi',
        'how are you'
    ]
    df.add_user_transition('root', 'x', nlu)
    df.update_state_settings('root', error_successor='y')
    df.user_turn('hi')
    assert df.state() == 'x'
示例#5
0
def test_transitions_to_transitions():
    df = DialogueFlow("root", initial_speaker=Speaker.SYSTEM)
    transitions = {
        "state": "root",
        '"Hello World!"': {"state": "state_2", "error": {'"Hi,"': "root->state_2"}},
    }
    df.load_transitions(transitions, speaker=Speaker.SYSTEM)
    assert df.system_turn() == "Hello World!"
    df.user_turn("blah")
    assert df.system_turn() == "Hi, Hello World!"
示例#6
0
 def __init__(self,
              initial_state,
              system_error_state,
              user_error_state,
              initial_speaker=DialogueFlow.Speaker.SYSTEM,
              macros=None,
              kb=None):
     if isinstance(system_error_state, str):
         system_error_state = ('SYSTEM', system_error_state)
     if isinstance(user_error_state, str):
         user_error_state = ('SYSTEM', user_error_state)
     # the dialogue flow currently controlling the conversation
     self._controller = DialogueFlow(initial_state, initial_speaker, macros,
                                     kb)
     self._controller_name = 'SYSTEM'
     # namespace : dialogue flow mapping
     self._components = {}
     self.add_component(self._controller, 'SYSTEM')
     self._system_error_state = system_error_state
     self._user_error_state = user_error_state
示例#7
0
def test_transitions_to_transitions():
    df = DialogueFlow('root', initial_speaker=Speaker.SYSTEM)
    transitions = {
        'state': 'root',

        '"Hello World!"': {
            'state': 'state_2',

            'error': {
                '"Hi,"': 'root->state_2'
            }
        }
    }
    df.load_transitions(transitions, speaker=Speaker.SYSTEM)
    assert df.system_turn() == 'Hello World!'
    df.user_turn('blah')
    assert df.system_turn() == 'Hi, Hello World!'
示例#8
0
def test_virtual_transitions_cross_module():
    df = DialogueFlow('root')
    transitions = {
        'state': 'root',
        'hello': {
            'state': 'test',
            'a': {'something typical'},
            '#VT(two:other)': 'blah'
        }
    }
    df.load_transitions(transitions)
    df2 = DialogueFlow('r2')
    transitions2 = {
        'not taken': {
            'state': 'other',
            'score': 0,
            'x': {
                'you win': {
                    'state': 'success'
                }
            },
            'y': {
                'you win': {
                    'state': 'success'
                }
            }
        }
    }
    df2.load_transitions(transitions2)
    cdf = CompositeDialogueFlow('one:root', 'e', 'e')
    cdf.add_component(df, 'one')
    cdf.add_component(df2, 'two')
    cdf.set_state('one:root')

    cdf.system_turn()
    assert cdf.state() == ('one', 'test')
    cdf.user_turn('x', debugging=True)
    assert cdf.system_turn() == 'you win'
    assert cdf.state() == ('two', 'success')
示例#9
0
def test_virtual_transitions_cross_module():
    df = DialogueFlow("root")
    transitions = {
        "state": "root",
        "hello": {
            "state": "test",
            "a": {"something typical"},
            "#VT(two:other)": "blah",
        },
    }
    df.load_transitions(transitions)
    df2 = DialogueFlow("r2")
    transitions2 = {
        "not taken": {
            "state": "other",
            "score": 0,
            "x": {
                "you win": {
                    "state": "success"
                }
            },
            "y": {
                "you win": {
                    "state": "success"
                }
            },
        }
    }
    df2.load_transitions(transitions2)
    cdf = CompositeDialogueFlow("one:root", "e", "e")
    cdf.add_component(df, "one")
    cdf.add_component(df2, "two")
    cdf.set_state("one:root")

    cdf.system_turn()
    assert cdf.state() == ("one", "test")
    cdf.user_turn("x", debugging=True)
    assert cdf.system_turn() == "you win"
    assert cdf.state() == ("two", "success")
示例#10
0
def test_user_transition():
    df = DialogueFlow(States.B)
    df.add_user_transition(States.B, States.C, "[{hi, hello, hey, [how, you]}]")
    df.add_user_transition(States.B, States.D, "[{bye, goodbye, see you, see ya, later}]")
    assert df.user_transition("oh hey there", df.state()) == States.C
    assert df.user_transition("well see ya later", df.state()) == States.D
示例#11
0
class CompositeDialogueFlow:
    def __init__(
        self,
        initial_state,
        system_error_state,
        user_error_state,
        initial_speaker=DialogueFlow.Speaker.SYSTEM,
        macros=None,
        kb=None,
    ):
        if isinstance(system_error_state, str):
            system_error_state = ("SYSTEM", system_error_state)
        if isinstance(user_error_state, str):
            user_error_state = ("SYSTEM", user_error_state)
        # the dialogue flow currently controlling the conversation
        self._controller = DialogueFlow(initial_state, initial_speaker, macros,
                                        kb)
        self._controller_name = "SYSTEM"
        # namespace : dialogue flow mapping
        self._components = {}
        self.add_component(self._controller, "SYSTEM")
        self._system_error_state = system_error_state
        self._user_error_state = user_error_state

    def run(self, debugging=False):
        """
        test in interactive mode
        :return: None
        """
        while True:
            if self.controller().speaker() == DialogueFlow.Speaker.SYSTEM:
                t1 = time()
                response = self.system_turn(debugging=debugging)
                if debugging:
                    print("System turn in {:5}".format(time() - t1))
                print("S:", response)
            else:
                user_input = input("U: ")
                t1 = time()
                self.user_turn(user_input, debugging=debugging)
                if debugging:
                    print("User turn in {:5}".format(time() - t1))

    def system_turn(self, debugging=False):
        """
        an entire system turn comprising a single system utterance and
        one or more system transitions
        :return: the natural language system response
        """
        visited = {self._controller.state()}
        self.controller().vars()["__goal_return_state__"] = "None"
        responses = []
        while self.controller().speaker() is DialogueFlow.Speaker.SYSTEM:
            try:
                response, next_state = self.controller().system_transition(
                    self.controller().state(), debugging=debugging)
                assert next_state is not None
                self.controller().set_state(next_state)
            except Exception as e:
                print()
                print(e)
                print(
                    "Error in CompositeDialogueFlow. Component: {}  State: {}".
                    format(self.controller_name(),
                           self.controller().state()))
                traceback.print_exc(file=sys.stdout)
                response, next_state = "", self._system_error_state
                visited = visited - {next_state}
            if isinstance(next_state, tuple):
                self.set_control(*next_state)
            responses.append(response)
            if next_state in visited or not self.state_settings(
                    *self.state()).system_multi_hop:
                self.controller().set_speaker(DialogueFlow.Speaker.USER)
            visited.add(next_state)
        full_response = " ".join(responses)
        self.controller().vars()["__selected_response__"] = full_response
        return full_response

    def user_turn(self, natural_language, debugging=False):
        """
        an entire user turn comprising one user utterance and
        one or more user transitions
        :param natural_language:
        :param debugging:
        :return: None
        """
        self.controller().vars()["__user_utterance__"] = natural_language
        try:
            self.controller().apply_update_rules(natural_language,
                                                 debugging=debugging)
            next_state = self.controller().state()
        except Exception as e:
            print()
            print(e)
            print("Error in CompositeDialogueFlow. Component: {}  State: {}".
                  format(self._controller_name,
                         self.controller().state()))
            traceback.print_exc(file=sys.stdout)
            next_state = self._user_error_state
        visited = {self.controller().state()}
        while self.controller().speaker() is DialogueFlow.Speaker.USER:
            try:
                next_state = self.controller().user_transition(
                    natural_language,
                    self.controller().state(),
                    debugging=debugging)
                assert next_state is not None
                self.controller().set_state(next_state)
            except Exception as e:
                print()
                print(e)
                print(
                    "Error in CompositeDialogueFlow. Component: {}  State: {}".
                    format(self._controller_name,
                           self.controller().state()))
                traceback.print_exc(file=sys.stdout)
                next_state = self._user_error_state
            next_state = module_state(next_state)
            if isinstance(next_state, tuple):
                self.set_control(*next_state)
                if self.state_settings(*self.state()).user_multi_hop:
                    self.controller().apply_update_rules(natural_language,
                                                         debugging=debugging)
            if next_state in visited or not self.state_settings(
                    *self.state()).user_multi_hop:
                self.controller().set_speaker(DialogueFlow.Speaker.SYSTEM)
            visited.add(next_state)
        next_state = module_state(next_state)
        if isinstance(next_state, tuple):
            self.set_control(*next_state)
            if self.controller().speaker() is DialogueFlow.Speaker.USER:
                self.controller().apply_update_rules(natural_language,
                                                     debugging=debugging)

    def set_control(self, namespace, state):
        state = module_state(state)
        speaker = self.controller().speaker()
        old_state = self.controller().state()
        self.component(namespace).set_state(old_state)
        self.set_controller(namespace)
        self.controller().set_speaker(speaker)
        if isinstance(state, tuple):
            umh = self.state_settings(*state).user_multi_hop
            smh = self.state_settings(*state).system_multi_hop
        else:
            umh = self.state_settings(namespace, state).user_multi_hop
            smh = self.state_settings(namespace, state).system_multi_hop
        if speaker == DialogueFlow.Speaker.USER and not umh:
            self.controller().change_speaker()
        elif speaker == DialogueFlow.Speaker.SYSTEM and not smh:
            self.controller().change_speaker()
        self.controller().set_state(state)

    def precache_transitions(self, process_num=1):
        start = time()

        transition_data_sets = []
        for i in range(process_num):
            transition_data_sets.append([])
        # count = 0

        if process_num == 1:
            for name, df in self._components.items():
                df.precache_transitions(process_num)
        else:
            # for name,df in self._components.items():
            #     for transition in df._graph.arcs():
            #         transition_data_sets[count].append(df._graph.arc_data(*transition))
            #         count = (count + 1) % process_num
            #
            # print("multiprocessing...")
            # p = Pool(process_num)
            # results = p.map(precache, transition_data_sets)
            # for i in range(len(results)):
            #     result_list = results[i]
            #     t_list = transition_data_sets[i]
            #     for j in range(len(result_list)):
            #         parsed_tree = result_list[j]
            #         t = t_list[j]
            #         t['natex']._compiler._parsed_tree = parsed_tree
            raise NotImplementedError()

        print("Elapsed: ", time() - start)

    def add_state(self, state, error_successor=None):
        state = module_state(state)
        if isinstance(state, tuple):
            ns, state = state
        else:
            ns = "SYSTEM"
        self._components[ns].add_state(state, error_successor)

    def add_user_transition(self, source, target, natex_nlu, **settings):
        source, target = module_source_target(source, target)
        if isinstance(source, tuple):
            ns, source = source
        else:
            ns = "SYSTEM"
        self._components[ns].add_user_transition(source, target, natex_nlu,
                                                 **settings)

    def add_system_transition(self, source, target, natex_nlg, **settings):
        source, target = module_source_target(source, target)
        if isinstance(source, tuple):
            ns, source = source
        else:
            ns = "SYSTEM"
        self._components[ns].add_system_transition(source, target, natex_nlg,
                                                   **settings)

    def add_component(self, component, namespace):
        self._components[namespace] = component
        component.set_is_module(self)
        component.set_namespace(namespace)
        component.set_gates(self.component("SYSTEM").gates())

    def component(self, namespace):
        return self._components[namespace]

    def components(self):
        return self._components.values()

    def set_state(self, state):
        state = module_state(state)
        if isinstance(state, tuple):
            if self.component(state[0]) != self.controller():
                self.component(state[0]).set_state(self.controller().state(
                ))  # so __system_state__ is set properly
                self.set_controller(state[0])
            state = state[1]
        self.controller().set_state(state)

    def set_controller(self, controller_name):
        old_controller_vars = self._controller.vars()
        if self._controller_name != controller_name:
            del old_controller_vars["__state__"]
        self._controller = self.component(controller_name)
        self._controller_name = controller_name
        new_controller_vars = self._controller.vars()
        new_controller_vars.update(old_controller_vars)
        self._controller.set_vars(new_controller_vars)

    def transition_natex(self, namespace, source, target, speaker):
        source, target = module_source_target(source, target)
        if isinstance(source, tuple):
            source = source[1]
        if isinstance(target, tuple):
            target = target[1]
        return self.component(namespace).transition_natex(
            source, target, speaker)

    def state_settings(self, namespace, state):
        return self.component(namespace).state_settings(state)

    def set_vars(self, vars):
        self._controller.set_vars(vars)

    def reset(self):
        gates = None
        goals = None
        for name, component in self._components.items():
            component.reset()
            if gates is None:
                gates = component.gates()
                goals = component.goals()
            component.set_gates(gates)
            component.set_goals(goals)
        self.set_controller("SYSTEM")

    def controller(self):
        return self._controller

    def controller_name(self):
        return self._controller_name

    def state(self):
        return self._controller_name, self._controller.state()

    def serialize(self):
        """
        Returns json serialized dict of
            {'vars': vars, 'gates': gates, 'state': state}
        """
        config = {
            "vars": self._controller.vars(),
            "gates": self._controller.gates(),
            "state": self.state()
        }
        return json_serialize_flexible(config, speaker_enum_mapping)

    def deserialize(self, config_str):
        config = json_deserialize_flexible(config_str, speaker_enum_rmapping)
        self.reset()
        self.set_state(config["state"])
        self.set_vars(config["vars"])
        gates = defaultdict(list, config["gates"])
        for name, component in self._components.items():
            component.set_gates(gates)

    def new_turn(self, toplevel="SYSTEM"):
        self.reset()
        self.set_controller(toplevel)
示例#12
0
def test_single_user_transition():
    df = DialogueFlow(States.B)
    df.add_user_transition(States.B, States.C, "[{hi, hello, hey, [how, you]}]")
    assert df.user_transition("oh hey there", df.state()) == States.C
示例#13
0
def test_system_transition():
    for _ in range(6):
        df = DialogueFlow(States.A)
        df.add_system_transition(States.A, States.B, "hello", score=2.0)
        df.add_system_transition(States.A, States.C, "hey")
        assert df.system_transition(df.state()) == ("hello", States.B)
        df = DialogueFlow(States.A)
        df.add_system_transition(States.A, States.B, "hello")
        df.add_system_transition(States.A, States.C, "hey", score=2.0)
        assert df.system_transition(df.state()) == ("hey", States.C)
示例#14
0
def test_virtual_transitions():
    df = DialogueFlow("root")
    transitions = {
        "state": "root",
        "hello": {
            "state": "test",
            "a": {
                "something typical": "nope"
            },
            "#VT(other)": "blah",
        },
        "not taken": {
            "state": "other",
            "score": 0,
            "x": {
                "you win": {
                    "state": "success"
                }
            },
            "y": {
                "you win": {
                    "state": "success"
                }
            },
        },
    }
    df.load_transitions(transitions)
    df.system_turn()
    assert df.state() == "test"
    df.user_turn("x", debugging=True)
    assert df.system_turn() == "you win"
    assert df.state() == "success"
示例#15
0
def test_information_state_based_dialogue():
    df = DialogueFlow("root", initial_speaker=Speaker.USER)
    df.add_user_transition("root", "one", "$x=[{cat, dog}]")
    df.set_error_successor("root", "one")
    df.add_system_transition("one", "root", "i am a stupid state machine")
    df.add_update_rule("[$x={ice cream, candy}]")
    df.add_update_rule("#ANY($x=candy)", "$y=blah")
    df.add_update_rule("#ANY($x=ice cream)", "$y=None")
    df.add_update_rule("#ANY($y=blah)", "i am a smart info state manager (2.0)")

    df.user_turn("candy", debugging=True)
    assert df.system_turn().strip() == "i am a smart info state manager"
    df.user_turn("ice cream", debugging=True)
    assert df.system_turn(debugging=True).strip() == "i am a stupid state machine"
    df.user_turn("ice cream", debugging=True)
    assert df.system_turn(debugging=True).strip() == "i am a stupid state machine"
    df.user_turn("ice cream", debugging=True)
    assert df.system_turn(debugging=True).strip() == "i am a stupid state machine"
    df.user_turn("ice cream", debugging=True)
    assert df.system_turn(debugging=True).strip() == "i am a stupid state machine"
示例#16
0
def test_gate_none():
    df = DialogueFlow("root")
    transitions = {
        "state": "root",
        "#GATE(var:None) hello": {
            "state": "greet",
            "score": 2.0,
            "hi": {"#SET($var=True) how are ya": {"error": "root"}},
            "error": {"how are you": {"error": "root"}},
        },
        "hi": "greet",
    }
    df.load_transitions(transitions)
    assert df.system_turn().strip() == "hello"
    df.user_turn("hi")
    assert df.system_turn().strip() == "how are ya"
    df.user_turn("fine")
    assert df.system_turn().strip() == "hi"
    df.user_turn("oh")
    assert df.system_turn().strip() == "how are you"
示例#17
0
def test_stack():
    df = DialogueFlow("root")
    transitions = {
        "state": "root",
        "`What should I do?`": "gma_hospital",
        "#GOAL(grandma_hospital) #GATE"
        "`I cannot concentrate on a lot of things right now. "
        "My grandma is in the hospital. "
        "What should I do?`": {
            "state": "gma_hospital",
            "score": 2.0,
            "[{[{dont,shouldnt,not},worry],calm,relax,distract,[mind,off]}]": {
                "state": "dont_worry",
                "#GATE "
                "\"Okay, I will try my best not to worry. It's hard because she lives by "
                "herself and won't let anyone help her very much, so I feel like this "
                'will just happen again."': {
                    "state": "happen_again",
                    "[{sorry,sucks,hard}]": {
                        '"yeah, thanks."': {}
                    },
                    "[will,better]": {
                        '"I really hope you are right."': {}
                    },
                    "error": {
                        "state": "feel_better",
                        '"I actually feel a little bit better after talking with you. Thanks for listening. "':
                        {},
                    },
                },
                "#DEFAULT": "feel_better",
            },
            "#IDK": {
                '"yeah, i dont know either. Its so tough."': {}
            },
        },
    }

    gma = {
        "#GOAL(why_grandma_hospital) "
        "[{[why,hospital],wrong,happened}]": {
            "state": "why_grandma_hospital",
            '"She is just so frail. I can hardly believe it. '
            'She fell off of a stool in the kitchen and broke her hip."': {
                "[dont worry]": {"#GRET(grandma_hospital,dont_worry)"},
                "error": {
                    "#GRET": "return"
                },
            },
        },
        "#GOAL(grandma_hospital_before) "
        "[{has,was},{she,grandma},hospital,{before,earlier,previously}]": {
            "state": "grandma_hospital_before",
            '"No, this is the first time, thank goodness."': {
                "error": {
                    "#GRET": "return"
                }
            },
        },
    }

    df.load_transitions(transitions)
    df.load_transitions(gma, speaker=DialogueFlow.Speaker.USER)
    df.add_global_nlu(
        "why_grandma_hospital",
        "#GOAL(why_grandma_hospital) [{[why,hospital],wrong,happened}]",
        score=0.7,
    )
    df.add_global_nlu(
        "grandma_hospital_before",
        "#GOAL(grandma_hospital_before) [{has,was},{she,grandma},hospital,{before,earlier,previously}]",
        score=0.7,
    )

    # r = df.system_turn()
    df.system_turn()
    assert df.vars()["__goal__"] == "grandma_hospital"
    assert len(df.vars()["__stack__"]) == 0
    assert df.state() == "gma_hospital"

    df.user_turn("what happened")
    assert df.state() == "why_grandma_hospital"
    assert df.vars()["__goal_return_state__"] == "None"
    assert df.vars()["__goal__"] == "why_grandma_hospital"
    assert len(df.vars()["__stack__"]) == 1
    assert df.vars()["__stack__"][0][0] == "grandma_hospital"

    assert "fell off of a stool" in df.system_turn()
    df.user_turn("oh no", debugging=True)

    assert "What should I do" in df.system_turn(debugging=True)
    assert df.state() == "gma_hospital"
    assert df.vars()["__goal__"] == "grandma_hospital"
    assert len(df.vars()["__stack__"]) == 0

    df.user_turn("dont worry")
    assert df.state() == "dont_worry"
    assert "she lives by herself" in df.system_turn()

    df.user_turn("has your grandma been in the hospital before this")
    assert df.state() == "grandma_hospital_before"
    assert df.vars()["__goal__"] == "grandma_hospital_before"
    assert len(df.vars()["__stack__"]) == 1
    assert df.vars()["__stack__"][0][0] == "grandma_hospital"

    assert "this is the first time" in df.system_turn()

    df.user_turn("ok that is good")
    assert "feel a little bit better" in df.system_turn()
    assert df.vars()["__goal__"] == "grandma_hospital"
    assert len(df.vars()["__stack__"]) == 0
示例#18
0
def test_system_multi_hop():
    df = DialogueFlow(States.A, initial_speaker=Speaker.SYSTEM)
    df.add_state(States.B, error_successor=States.B, system_multi_hop=True)
    df.add_state(States.C, error_successor=States.A, system_multi_hop=True)
    df.add_state(States.D, error_successor=States.A)
    df.add_state(States.E, error_successor=States.A)
    df.add_system_transition(States.A, States.B, "{hey, hello}")
    df.add_system_transition(States.A, States.C, "excuse me")
    df.add_system_transition(States.B, States.D, "how are you")
    df.add_system_transition(States.C, States.E, "what")
    for _ in range(100):
        df.set_state(States.A)
        df.set_speaker(Speaker.SYSTEM)
        response = df.system_turn()
        assert response in {"hey how are you", "hello how are you", "excuse me what"}
示例#19
0
def test_user_multi_hop():
    df = DialogueFlow(States.A, initial_speaker=Speaker.USER)
    df.add_state(States.B, error_successor=States.B, user_multi_hop=True)
    df.add_state(States.C, error_successor=States.A, user_multi_hop=True)
    df.add_state(States.D, error_successor=States.A)
    df.add_state(States.E, error_successor=States.A)
    df.add_user_transition(States.A, States.B, "[{hey, hello}]")
    df.add_user_transition(States.A, States.C, "[{excuse, pardon}]")
    df.add_user_transition(States.B, States.D, "[how, you]")
    df.add_user_transition(States.C, States.E, "[{where, how, what}]")
    df.set_state(States.A)
    df.user_turn("hey", debugging=False)
    assert df.state() == States.B
    df.set_state(States.A)
    df.set_speaker(Speaker.USER)
    df.user_turn("hey how are you")
    assert df.state() == States.D
    df.set_state(States.A)
    df.set_speaker(Speaker.USER)
    df.user_turn("excuse me where do i go")
    assert df.state() == States.E
    df.set_state(States.A)
    df.set_speaker(Speaker.USER)
    df.user_turn("excuse me")
    assert df.state() == States.A
示例#20
0
def test_information_state_state_set():
    df = DialogueFlow("root", initial_speaker=Speaker.USER)
    transitions = {
        "state": "root",
        "error": {
            "state": "one",
            "okay": {"state": "two", "error": {"state": "three", "sure": "root"}},
        },
        "something": {"state": "special", "that is great": "root"},
    }
    df.add_update_rule("[{read, watched}]", "#TRANSITION(special, 2.0)")
    df.load_transitions(transitions, speaker=Speaker.USER)
    df.user_turn("hi")
    assert df.system_turn() == "okay"
    df.user_turn("i read a book")
    assert df.state() == "special"
    assert df.system_turn() == "that is great"
    assert df.state() == "root"
示例#21
0
def test_add_transitions():
    df = DialogueFlow("States.A")
    df.add_system_transition("States.A", "States.B", "hello")
    df.add_user_transition("States.B", "States.C", "[{hi, hello, hey, [how, you]}]")
    df.add_user_transition("States.B", "States.D", "[{dog, cat, parrot}]")
    df.add_system_transition("States.D", "States.A", "so")
    assert df.graph().arcs() == {
        ("States.A", "States.B", DialogueFlow.Speaker.SYSTEM),
        ("States.B", "States.C", DialogueFlow.Speaker.USER),
        ("States.B", "States.D", DialogueFlow.Speaker.USER),
        ("States.D", "States.A", DialogueFlow.Speaker.SYSTEM),
    }
    assert isinstance(df.transition_natex("States.A", "States.B", Speaker.SYSTEM), NatexNLG)
    assert isinstance(df.transition_natex("States.B", "States.C", Speaker.USER), NatexNLU)
示例#22
0
def test_reset():
    df = DialogueFlow(States.A, initial_speaker=Speaker.SYSTEM)
    df.add_state(States.B, error_successor=States.E)
    df.add_state(States.C, error_successor=States.E)
    df.add_system_transition(States.A, States.B, "B")
    df.add_system_transition(States.A, States.C, "C")
    df.add_system_transition(States.E, States.E, "E")

    # response = df.system_turn()
    df.system_turn()
    df.user_turn("")
    assert df.state() == States.E

    df.reset()
    assert df.state() == "States.A"
    assert df.speaker() == Speaker.SYSTEM
    # response = df.system_turn()
    df.system_turn()
    df.user_turn("")
    assert df.state() == States.E
    df.system_turn()
    assert df.state() == States.E

    df.reset()
    assert df.state() == States.A
    assert df.speaker() == Speaker.SYSTEM
    # response = df.system_turn()
    df.system_turn()
    df.user_turn("")
    assert df.state() == States.E
    df.system_turn()
    assert df.state() == States.E
示例#23
0
def test_global_transition_list_disjunction():
    df = DialogueFlow("root", initial_speaker=Speaker.USER)
    nlu = ["hi", "hello"]
    df.add_state("root", "x")
    df.add_system_transition("x", "y", "hello")
    df.add_global_nlu("x", nlu)
    df.user_turn("ok")
    df.system_turn()
    df.user_turn("hi")
    assert df.state() == "x"
示例#24
0
def test_enter_natex():
    df = DialogueFlow("root")
    transitions = {
        "state": "root",
        "hello": {"state": "one", "score": 2.0, "enter": "#GATE", "error": "root"},
        "hi": {"state": "two", "score": 1.0, "enter": "#GATE", "error": "root"},
        "bye": {
            "state": "one",
            "score": 1.0,
        },
        "goodbye": {"state": "three", "score": 0.0, "error": "end"},
    }
    df.load_transitions(transitions)
    assert df.system_turn() == "hello"
    df.user_turn("hello")
    assert df.system_turn() == "hi"
    df.user_turn("hi")
    assert df.system_turn() == "goodbye"
示例#25
0
def test_check():
    df = DialogueFlow(States.A)
    df.add_state(States.B, error_successor=States.C)
    df.add_state(States.D, error_successor=States.A)
    df.add_system_transition(States.A, States.B, "hello")
    df.add_user_transition(States.B, States.C, "[{hi, hello, hey, [how, you]}]")
    df.add_user_transition(States.B, States.A, "[{bye, goodbye, see you, see ya, later}]")
    df.add_system_transition(States.C, States.D, "ok")
    assert df.check()
    df = DialogueFlow(States.A)
    df.add_state(States.B, error_successor=States.C)
    df.add_system_transition(States.A, States.B, "hello")
    df.add_user_transition(States.B, States.C, "[{hi, hello, hey, [how, you]}]")
    df.add_user_transition(States.B, States.A, "[{bye, goodbye, see you, see ya, later}]")
    df.add_system_transition(States.C, States.D, "ok")
    assert not df.check()
    df = DialogueFlow(States.A)
    df.add_state(States.B, error_successor=States.C)
    df.add_state(States.D, error_successor=States.A)
    df.add_system_transition(States.A, States.B, "hello")
    df.add_user_transition(States.B, States.C, "[{hi, hello, hey, [how, you]}]")
    df.add_user_transition(States.B, States.A, "[{bye, goodbye, see you, see ya, later}]")
    df.add_system_transition(States.C, States.D, "ok then $X alright")
    assert not df.check()
示例#26
0
def test_serialization():
    df = DialogueFlow(States.A, initial_speaker=Speaker.SYSTEM)
    df.add_state(States.B, error_successor=States.E)
    df.add_state(States.C, error_successor=States.E)
    df.add_system_transition(States.A, States.B, "#GATE $spoken=B")
    df.add_system_transition(States.A, States.C, "#GATE(spoken) $spoken=C")
    df.add_system_transition(States.E, States.E, "$spoken=E")
    df.add_user_transition(States.B, States.A, "$heard=b")
    df.add_user_transition(States.E, States.A, "$heard=e")

    df.system_turn()
    assert df.state() == States.B
    assert df.vars()["spoken"] == "B"
    df.user_turn("b")
    df.system_turn()
    assert df.state() == States.C
    assert df.vars()["spoken"] == "C"
    expected_gates = {"States.B": [{}], "States.C": [{"spoken": "B"}]}
    assert df.gates() == expected_gates
    df.vars()["testing_none"] = None
    d = df.serialize()

    df2 = DialogueFlow(States.A, initial_speaker=Speaker.SYSTEM)
    df2.add_state(States.B, error_successor=States.E)
    df2.add_state(States.C, error_successor=States.E)
    df2.add_system_transition(States.A, States.B, "#GATE $spoken=B")
    df2.add_system_transition(States.A, States.C, "#GATE(spoken) $spoken=C")
    df2.add_system_transition(States.E, States.E, "$spoken=E")
    df2.add_user_transition(States.B, States.A, "$heard=b")
    df2.add_user_transition(States.E, States.A, "$heard=e")
    assert df2.state() == States.A
    assert "spoken" not in df2.vars() and "heard" not in df2.vars()
    assert len(df2.gates()) == 0

    df2.deserialize(d)

    assert df.vars() == df2.vars()
    assert df.gates() == df2.gates()
    assert df.state() == df2.state()
    assert df2.vars()["testing_none"] is None
示例#27
0
    ("panther", "sound", "growl"),
    ("growl", "quality", "scary"),
    ("also", "type", "also_syns"),
    ("too", "type", "also_syns"),
    ("basketball", "type", "unknown_hobby"),
    ("basketball", "expr", "bball"),
    ("john", "type", "male"),
    ("mary", "type", "female"),
    ("male", "type", "person"),
    ("female", "type", "person"),
    ("friend", "type", "person"),
])
ont = {"ontology": {"person": ["mom", "dad", "sister", "brother"]}}
kb.load_json(ont)

df = DialogueFlow(initial_state="start")
df.add_state("start", "start")
df.add_system_transition("start", "start", "hello")

macros = {
    # "ONT": ONTE(kb),
    # "KBQ": KBE(kb),
    # "EXP": EXP(kb),
    # "U": UnionMacro(),
    # "I": Intersection(),
    # "DIF": Difference(),
    # "SET": SetVars(),
    # "ALL": CheckVarsConjunction(),
    # "ANY": CheckVarsDisjunction(),
    # "NOT": NOT(),
    # "ISP": IsPlural(),
示例#28
0
def test_single_system_transition():
    df = DialogueFlow(States.A)
    df.add_system_transition(States.A, States.B, "hello")
    assert df.system_transition(df.state()) == ("hello", States.B)
示例#29
0
def test_global_transition_priority():
    df = DialogueFlow("root")
    transitions = {
        "state": "root",
        "hello": {
            "[oh]": {"score": 0.6, "okay": {}},
            "[wow]": {"score": 2.0, "alright": {}},
        },
    }
    df.add_global_nlu("root", "/.*/", score=0.7)
    df.load_transitions(transitions)
    df.system_turn()
    df.user_turn("oh wow")
    assert df.system_turn() == "alright"
示例#30
0
def test_constructor():
    df = DialogueFlow(States.A)
    assert df.state() == States.A
    assert df.speaker() == Speaker.SYSTEM