コード例 #1
0
def _check_condition(node, condition):
    if "type" not in condition:
        reason = "condition_group字段中每个判断条件必须有type字段"
        raise DialogueStaticCheckException("condition_group", reason,
                                           node.node_name)

    if "operator" not in condition:
        reason = "condition_group字段中每个判断条件必须有operator字段"
        raise DialogueStaticCheckException("condition_group", reason,
                                           node.node_name)

    operator_options = ["==", "!=", ">", "<", "<=", ">=", "like", "isNull", "isNotNull"]
    if condition["operator"] not in operator_options:
        reason = "condition_group字段中operator字段必须是{}其中之一。而现在是{}".format(
            operator_options, condition["operator"])

    type_options = ["intent", "entity", "global", "params"]
    if condition["type"] not in type_options:
        reason = "condition_group字段中type字段必须是{}其中之一,而现在是{}".format(
            type_options, condition["type"])
        raise DialogueStaticCheckException("condition_group", reason,
                                           node.node_name)

    if condition["type"] in type_options[1:] and "value" not in condition:
        reason = "condition_group字段中如果条件判断类型为{},则必须指定value字段".format(
            condition["type"])
コード例 #2
0
    def build_graph(self, graph):
        """
        将对话流程配置构造成节点图
        """
        nodes_mapping = {}
        for node_meta in graph["nodes"]:
            node_type = node_meta["node_type"]
            node_id = node_meta["node_id"]
            if node_type not in TYPE_NODE_MAPPING:
                raise DialogueStaticCheckException(
                    "node_type", "没有这种类型的节点: {}".format(node_type), node_id)
            node_class = TYPE_NODE_MAPPING[node_type]
            nodes_mapping[node_id] = node_class(node_meta)
            # 静态检查节点
            try:
                nodes_mapping[node_id].static_check()
            except DialogueStaticCheckException as e:
                e.update_optional_params(robot_code=self.robot_code,
                                         graph_id=graph.get("id", "unknown"))
                raise e

        for conn in graph["connections"]:
            if "source_id" not in conn or "target_id" not in conn:
                raise DialogueStaticCheckException(
                    conn.get("line_id", "unkown"),
                    reason="连接线必须有source_id和target_id字段",
                    robot_code=self.robot_code,
                    graph_id=graph.get("graph_id", "unknown"),
                    node_id=conn.get("line_id", "未知(连接线没有line_id字段)"))
            source_node = nodes_mapping[conn["source_id"]]
            target_node = nodes_mapping[conn["target_id"]]
            line_id = conn["line_id"]
            branch_id = conn.get("branch_id", None)
            intent_id = conn.get("intent_id", None)
            option_id = conn.get("options", None)
            if branch_id and intent_id:
                raise DialogueStaticCheckException(
                    conn.get("line_id", "unkown"),
                    "连接线不能同时指定branch_id, intent_id参数",
                    robot_code=self.robot_code,
                    graph_id=graph.get("graph_id", "unknown"),
                    node_id=conn.get("line_id", "未知(连接线没有line_id字段)"))
            source_node.add_child(target_node, line_id, branch_id, intent_id,
                                  option_id)

        start_nodes = [
            nodes_mapping[node_id] for node_id in graph["start_nodes"]
        ]

        for node in start_nodes:
            if not isinstance(node, nodes.StartNode):
                raise DialogueStaticCheckException(
                    "node_type", "对话流程根节点的类型必须是开始节点",
                    node.config.get("node_id", "未知"))
        return start_nodes
コード例 #3
0
def fill_slot_node_slots_checker(node, slots):
    if not isinstance(slots, list):
        reason = "填槽节点的slots字段必须是list类型,现在是{}类型".format(type(slots))
        raise DialogueStaticCheckException("slots", reason, node.node_name)

    for slot in slots:
        if "slot_name" not in slot or not isinstance(slot["slot_name"], str):
            reason = "填槽节点的slots字段中每个元素必须有slot_name字段,并且必须是str类型"
            raise DialogueStaticCheckException("slots", reason, node.node_name)

        if "multi" not in slot or not isinstance(slot["multi"], bool):
            reason = "填槽节点的slots字段中每个元素必须有multi字段,并且必须是bool类型"
            raise DialogueStaticCheckException("slots", reason, node.node_name)

        if "rounds" not in slot or not isinstance(slot["rounds"], int):
            reason = "填槽节点的slots字段每个元素必须有rounds字段,并且必须是int类型"
            raise DialogueStaticCheckException("slots", reason, node.node_name)

        if "reask_words" not in slot or not isinstance(slot["reask_words"],
                                                       list):
            reason = "填槽节点的slots字段中每个元素必须有reask_words字段,并且必须是list类型"
            raise DialogueStaticCheckException("slots", reason, node.node_name)
        if "callback_words" not in slot or not isinstance(
                slot["callback_words"], list):
            reason = "填槽节点的slots字段中每个元素必须有callback_words字段,并且必须是list类型"
            raise DialogueStaticCheckException("slots", reason, node.node_name)

        if "is_necessary" not in slot or not isinstance(
                slot["is_necessary"], bool):
            reason = "填槽节点的slots字段中每个元素必须有is_necessary字段,并且必须是bool类型"
            raise DialogueStaticCheckException("slots", reason, node.node_name)
コード例 #4
0
def start_node_conditional_checker(node, value):
    if not isinstance(value, list):
        reason = "slots字段的类型必须是list,而现在是{}".format(type(value))
        raise DialogueStaticCheckException("slots", reason, node.node_name)

    for group in value:
        if not isinstance(group, list):
            reason = "condition_group字段中每个group的类型必须是list,目前是{}".format(
                type(group))

        for condition in group:
            _check_condition(node, condition)
コード例 #5
0
def judge_node_conditional_checker(node, branchs):
    if not isinstance(branchs, list):
        reason = "branchs字段的类型必须是list,而现在是{}".format(type(branchs))
        raise DialogueStaticCheckException("branchs",
                                           reason=reason,
                                           node_id=node.node_name)

    for branch in branchs:
        if not isinstance(branch, dict):
            reason = "branchs字段中每个branch的类型必须是dict,目前是{}".format(type(branch))
            raise DialogueStaticCheckException("branchs",
                                               reason,
                                               node_id=node.node_name)

        if "branch_id" not in branch:
            reason = "branchs字段中的每个branch中必须有branch_id字段"
            raise DialogueStaticCheckException("branchs",
                                               reason,
                                               node_id=node.node_name)

        if "conditions" not in branch or not isinstance(
                branch["conditions"], list):
            reason = "branchs字段中的每个group必须有conditions字段,并且是list类型"
            raise DialogueStaticCheckException("branchs",
                                               reason,
                                               node_id=node.node_name)

        for condition in branch["conditions"]:
            if not isinstance(condition, list):
                reason = "branchs字段中每个group的conditions字段必须是list,而现在是{}".format(
                    type(condition))
                raise DialogueStaticCheckException("slots",
                                                   reason=reason,
                                                   node_id=node.node_name)

            for group in condition:
                _check_condition(node, group)
コード例 #6
0
    def check(node, _):
        callback_in = "callback_words" in node.config
        life_cycle_in = "life_cycle" in node.config

        if life_cycle_in and not callback_in or (not life_cycle_in
                                                 and callback_in):
            reason = "节点类型{}的配置中必须同时包含或者同时不包含callback_words和life_cycle两个字段。".format(
                node.NODE_NAME)
            raise DialogueStaticCheckException("callback_words, life_cycle",
                                               reason, node.node_name)

        if life_cycle_in and callback_in:
            simple_type_checker("callback_words",
                                list)(node, node.config["callback_words"])
            simple_type_checker("life_cycle", int)(node,
                                                   node.config["life_cycle"])
コード例 #7
0
    def static_check(self):
        """
        静态检查配置的数据结构
        """
        required_checkers = chain(self.base_checkers.items(),
                                  self.required_checkers.items())
        for key, func in required_checkers:
            if key in self.config:
                func(self, self.config[key])
            else:
                raise DialogueStaticCheckException(key, "该节点缺少此必填字段",
                                                   self.node_name)

        for key, func in self.optional_checkers.items():
            if key in self.config:
                func(self, self.config[key])
コード例 #8
0
 def check(node, value):
     if value not in ref_values:
         reason = "字段key的值必须是{}中的值之一," \
             " 而不是{}。".format(ref_values, value)
         raise DialogueStaticCheckException(key, reason, node.node_name)
コード例 #9
0
 def check(node, value):
     if not isinstance(value, dtype):
         reason = "字段{}的值必须是类型{}," \
             "但是配置的类型是{}。".format(key, get_class_name(
                 dtype), get_class_name(type(value)))
         raise DialogueStaticCheckException(key, reason, node.node_name)