diff --git a/dff/utils/viewer/preprocessing.py b/dff/utils/viewer/preprocessing.py index 3df3b15b3..87d832e2f 100644 --- a/dff/utils/viewer/preprocessing.py +++ b/dff/utils/viewer/preprocessing.py @@ -14,7 +14,7 @@ def get_script(nx_graph: nx.Graph, node_data: dict) -> dict: def get_label_by_index_shifting( nx_graph: nx.Graph, node_id: tuple, increment_flag: bool = True, cyclicality_flag: bool = True ) -> tuple: - if node_id == ("NONE",) or node_id == ("NODE", "GLOBAL"): # fall back on skip conditions + if node_id == ("NONE",) or node_id == ("GLOBAL_NODE", "GLOBAL"): # fall back on skip conditions return ("NODE", *nx_graph.graph["fallback_label"]) script = get_script(nx_graph, nx_graph.nodes[node_id]) _, flow, *info = node_id @@ -39,9 +39,9 @@ def resolve_labels(nx_graph: nx.Graph, edge: tuple, edge_data: dict) -> dict: _, *source_info = source_node # get label transition sources - if source_info[0] == "GLOBAL": + if source_info[0] == "GLOBAL_NODE": sources = [node for node in nx_graph.nodes.keys() if node[0] != "LABEL" and node[0] != "NONE"] - elif source_info[1] == "LOCAL": + elif source_info[0] == "LOCAL_NODE": sources = [node for node in nx_graph.nodes.keys() if node[1] == source_info[0] and node[0] != "NONE"] else: sources = [source_node] @@ -68,7 +68,7 @@ def transform_virtual(node: tuple): """ Put special nodes to virtual flow. Replace NONE with unresolved key constant. """ - if node == ("NODE", "GLOBAL"): + if node == ("GLOBAL_NODE", "GLOBAL"): return ("NODE", VIRTUAL_FLOW_KEY, node[-1]) elif node == ("NONE",): return ("NODE", VIRTUAL_FLOW_KEY, UNRESOLVED_KEY) @@ -93,8 +93,8 @@ def preprocess( nx_graph.remove_nodes_from(list(node for node in nx_graph.nodes if node[0] == "LABEL")) - if not show_global and ("NODE", "GLOBAL") in nx_graph.nodes: - nx_graph.remove_nodes_from([("NODE", "GLOBAL")]) + if not show_global and ("GLOBAL_NODE", "GLOBAL") in nx_graph.nodes: + nx_graph.remove_nodes_from([("GLOBAL_NODE", "GLOBAL")]) if not show_local: nx_graph.remove_nodes_from(list(node for node in nx_graph.nodes if node[-1] == "LOCAL")) diff --git a/setup.py b/setup.py index d40101ef5..f18dcf074 100644 --- a/setup.py +++ b/setup.py @@ -114,7 +114,7 @@ def merge_req_lists(*req_lists: List[str]) -> List[str]: ydb_dependencies, telegram_dependencies, parser_dependencies, - script_viewer_dependencies + script_viewer_dependencies, ) requests_requirements = [ diff --git a/tests/viewer/opts_off.dot b/tests/viewer/opts_off.dot index e2c80a49e..b16b074b6 100644 --- a/tests/viewer/opts_off.dot +++ b/tests/viewer/opts_off.dot @@ -14,67 +14,51 @@ digraph { label=GREETING_FLOW, style="rounded, filled" ]; - "('NODE', \"'greeting_flow'\", \"'node1'\")" [label=<

NODE1


Transitions
(
cnd.true())
(
cnd.true())
(
cnd.regexp('how are you'))
(
cnd.all([cnd.regexp('next\\b'), cnd.has_last_labels(labels=[('music_flow', i) for i in ['node2', 'node3']])]))
(
cnd.all([cnd.regexp('repeat', re.I), cnd.negation(cnd.has_last_labels(flow_labels=['global_flow']))]))
>]; - "('NODE', \"'greeting_flow'\", \"'node2'\")" [label=<

NODE2


Transitions
(
cnd.regexp('talk about music'))
(
cnd.true())
(
cnd.true())
(
cnd.all([cnd.regexp('next\\b'), cnd.has_last_labels(labels=[('music_flow', i) for i in ['node2', 'node3']])]))
(
cnd.regexp('talk about'))
(
cnd.all([cnd.regexp('repeat', re.I), cnd.negation(cnd.has_last_labels(flow_labels=['global_flow']))]))
>]; - "('NODE', \"'greeting_flow'\", \"'node3'\")" [label=<

NODE3


Transitions
(
cnd.true())
(
cnd.all([cnd.regexp('next\\b'), cnd.has_last_labels(labels=[('music_flow', i) for i in ['node2', 'node3']])]))
(
cnd.regexp('bye'))
(
cnd.all([cnd.regexp('repeat', re.I), cnd.negation(cnd.has_last_labels(flow_labels=['global_flow']))]))
>]; - "('NODE', \"'greeting_flow'\", \"'node4'\")" [label=<

NODE4


Transitions
(
cnd.regexp('hi|hello', re.IGNORECASE))
(
cnd.all([cnd.regexp('next\\b'), cnd.has_last_labels(labels=[('music_flow', i) for i in ['node2', 'node3']])]))
(
cnd.true())
(
cnd.true())
(
cnd.all([cnd.regexp('repeat', re.I), cnd.negation(cnd.has_last_labels(flow_labels=['global_flow']))]))
>]; + "('NODE', \"'greeting_flow'\", \"'node1'\")" [label=<

NODE1


Transitions
(
cnd.true())
(
cnd.regexp('how are you'))
>]; + "('NODE', \"'greeting_flow'\", \"'node2'\")" [label=<

NODE2


Transitions
(
cnd.regexp('talk about music'))
(
cnd.true())
(
cnd.regexp('talk about'))
>]; + "('NODE', \"'greeting_flow'\", \"'node3'\")" [label=<

NODE3


Transitions
(
cnd.regexp('bye'))
>]; + "('NODE', \"'greeting_flow'\", \"'node4'\")" [label=<

NODE4


Transitions
(
cnd.regexp('hi|hello', re.IGNORECASE))
(
cnd.true())
>]; } subgraph "cluster_'music_flow'" { graph [color="#c6ae82", label=MUSIC_FLOW, style="rounded, filled" ]; - "('NODE', \"'music_flow'\", \"'node1'\")" [label=<

NODE1


Transitions
(
cnd.true())
(
cnd.true())
(
cnd.all([cnd.regexp('next\\b'), cnd.has_last_labels(labels=[('music_flow', i) for i in ['node2', 'node3']])]))
(
cnd.regexp('yes|yep|ok', re.IGNORECASE))
(
cnd.all([cnd.regexp('repeat', re.I), cnd.negation(cnd.has_last_labels(flow_labels=['global_flow']))]))
>]; - "('NODE', \"'music_flow'\", \"'node2'\")" [label=<

NODE2


Transitions
(
cnd.true())
(
cnd.true())
(
cnd.all([cnd.regexp('next\\b'), cnd.has_last_labels(labels=[('music_flow', i) for i in ['node2', 'node3']])]))
(
cnd.regexp('next', re.IGNORECASE))
(
cnd.all([cnd.regexp('repeat', re.I), cnd.negation(cnd.has_last_labels(flow_labels=['global_flow']))]))
(
cnd.regexp('repeat', re.IGNORECASE))
>]; - "('NODE', \"'music_flow'\", \"'node3'\")" [label=<

NODE3


Transitions
(
cnd.true())
(
cnd.true())
(
cnd.all([cnd.regexp('next\\b'), cnd.has_last_labels(labels=[('music_flow', i) for i in ['node2', 'node3']])]))
(
cnd.regexp('next', re.IGNORECASE))
(
cnd.all([cnd.regexp('repeat', re.I), cnd.negation(cnd.has_last_labels(flow_labels=['global_flow']))]))
(
cnd.regexp('repeat', re.IGNORECASE))
(
cnd.regexp('back', re.IGNORECASE))
>]; - "('NODE', \"'music_flow'\", \"'node4'\")" [label=<

NODE4


Transitions
(
cnd.true())
(
cnd.true())
(
cnd.all([cnd.regexp('next\\b'), cnd.has_last_labels(labels=[('music_flow', i) for i in ['node2', 'node3']])]))
(
cnd.all([cnd.regexp('repeat', re.I), cnd.negation(cnd.has_last_labels(flow_labels=['global_flow']))]))
>]; + "('NODE', \"'music_flow'\", \"'node1'\")" [label=<

NODE1


Transitions
(
cnd.regexp('yes|yep|ok', re.IGNORECASE))
(
cnd.true())
>]; + "('NODE', \"'music_flow'\", \"'node2'\")" [label=<

NODE2


Transitions
(
cnd.regexp('next', re.IGNORECASE))
(
cnd.regexp('repeat', re.IGNORECASE))
(
cnd.true())
>]; + "('NODE', \"'music_flow'\", \"'node3'\")" [label=<

NODE3


Transitions
(
cnd.regexp('next', re.IGNORECASE))
(
cnd.regexp('back', re.IGNORECASE))
(
cnd.regexp('repeat', re.IGNORECASE))
(
cnd.true())
>]; + "('NODE', \"'music_flow'\", \"'node4'\")" [label=<

NODE4


Transitions
(
cnd.true())
>]; } subgraph "cluster_'global_flow'" { graph [color="#f78378", label=GLOBAL_FLOW, style="rounded, filled" ]; - "('NODE', \"'global_flow'\", \"'fallback_node'\")" [label=<

FALLBACK_NODE


Transitions
(
cnd.regexp('talk about music'))
(
cnd.regexp('hi|hello', re.IGNORECASE))
(
cnd.true())
(
cnd.all([cnd.regexp('next\\b'), cnd.has_last_labels(labels=[('music_flow', i) for i in ['node2', 'node3']])]))
(
cnd.all([cnd.regexp('repeat', re.I), cnd.negation(cnd.has_last_labels(flow_labels=['global_flow']))]))
(
cnd.true())
>]; - "('NODE', \"'global_flow'\", \"'start_node'\")" [label=<

START_NODE


Transitions
(
cnd.regexp('talk about music'))
(
cnd.regexp('hi|hello', re.IGNORECASE))
(
cnd.true())
(
cnd.true())
(
cnd.all([cnd.regexp('next\\b'), cnd.has_last_labels(labels=[('music_flow', i) for i in ['node2', 'node3']])]))
(
cnd.all([cnd.regexp('repeat', re.I), cnd.negation(cnd.has_last_labels(flow_labels=['global_flow']))]))
>]; + "('NODE', \"'global_flow'\", \"'fallback_node'\")" [label=<

FALLBACK_NODE


Transitions
(
cnd.regexp('talk about music'))
(
cnd.regexp('hi|hello', re.IGNORECASE))
(
cnd.true())
>]; + "('NODE', \"'global_flow'\", \"'start_node'\")" [label=<

START_NODE


Transitions
(
cnd.regexp('talk about music'))
(
cnd.regexp('hi|hello', re.IGNORECASE))
(
cnd.true())
>]; } - "('NODE', \"'greeting_flow'\", \"'node1'\")":repeat -> "('NODE', \"'greeting_flow'\", \"'node1'\")"; "('NODE', \"'greeting_flow'\", \"'node1'\")":"('global_flow', 'fallback_node', 0.1)" -> "('NODE', \"'global_flow'\", \"'fallback_node'\")"; - "('NODE', \"'greeting_flow'\", \"'node1'\")":to_fallback -> "('NODE', \"'global_flow'\", \"'fallback_node'\")"; "('NODE', \"'greeting_flow'\", \"'node1'\")":"'node2'" -> "('NODE', \"'greeting_flow'\", \"'node2'\")"; - "('NODE', \"'greeting_flow'\", \"'node1'\")":forward -> "('NODE', \"'greeting_flow'\", \"'node2'\")"; "('NODE', \"'global_flow'\", \"'fallback_node'\")":"('greeting_flow', 'node1')" -> "('NODE', \"'greeting_flow'\", \"'node1'\")"; - "('NODE', \"'global_flow'\", \"'fallback_node'\")":to_fallback -> "('NODE', \"'global_flow'\", \"'fallback_node'\")"; - "('NODE', \"'global_flow'\", \"'fallback_node'\")":forward -> "('NODE', \"'global_flow'\", \"'fallback_node'\")"; "('NODE', \"'global_flow'\", \"'fallback_node'\")":repeat -> "('NODE', \"'global_flow'\", \"'fallback_node'\")"; "('NODE', \"'global_flow'\", \"'fallback_node'\")":"('music_flow', 'node1')" -> "('NODE', \"'music_flow'\", \"'node1'\")"; "('NODE', \"'greeting_flow'\", \"'node2'\")":to_fallback -> "('NODE', \"'global_flow'\", \"'fallback_node'\")"; - "('NODE', \"'greeting_flow'\", \"'node2'\")":repeat -> "('NODE', \"'greeting_flow'\", \"'node2'\")"; "('NODE', \"'greeting_flow'\", \"'node2'\")":"('music_flow', 'node1')" -> "('NODE', \"'music_flow'\", \"'node1'\")"; - "('NODE', \"'greeting_flow'\", \"'node2'\")":forward -> "('NODE', \"'greeting_flow'\", \"'node3'\")"; + "('NODE', \"'greeting_flow'\", \"'node2'\")":forward -> "('NODE', \"'greeting_flow'\", \"'node3'\")" [minlen=1]; "('NODE', \"'music_flow'\", \"'node1'\")":to_fallback -> "('NODE', \"'global_flow'\", \"'fallback_node'\")"; - "('NODE', \"'music_flow'\", \"'node1'\")":repeat -> "('NODE', \"'music_flow'\", \"'node1'\")"; "('NODE', \"'music_flow'\", \"'node1'\")":forward -> "('NODE', \"'music_flow'\", \"'node2'\")"; "('NODE', \"'music_flow'\", \"'node2'\")":to_fallback -> "('NODE', \"'global_flow'\", \"'fallback_node'\")"; "('NODE', \"'music_flow'\", \"'node2'\")":repeat -> "('NODE', \"'music_flow'\", \"'node2'\")"; "('NODE', \"'music_flow'\", \"'node2'\")":forward -> "('NODE', \"'music_flow'\", \"'node3'\")"; "('NODE', \"'global_flow'\", \"'start_node'\")":"('greeting_flow', 'node1')" -> "('NODE', \"'greeting_flow'\", \"'node1'\")"; "('NODE', \"'global_flow'\", \"'start_node'\")":"'fallback_node'" -> "('NODE', \"'global_flow'\", \"'fallback_node'\")"; - "('NODE', \"'global_flow'\", \"'start_node'\")":to_fallback -> "('NODE', \"'global_flow'\", \"'fallback_node'\")"; - "('NODE', \"'global_flow'\", \"'start_node'\")":forward -> "('NODE', \"'global_flow'\", \"'fallback_node'\")"; "('NODE', \"'global_flow'\", \"'start_node'\")":"('music_flow', 'node1')" -> "('NODE', \"'music_flow'\", \"'node1'\")"; - "('NODE', \"'global_flow'\", \"'start_node'\")":repeat -> "('NODE', \"'global_flow'\", \"'start_node'\")"; - "('NODE', \"'greeting_flow'\", \"'node3'\")":to_fallback -> "('NODE', \"'global_flow'\", \"'fallback_node'\")"; - "('NODE', \"'greeting_flow'\", \"'node3'\")":repeat -> "('NODE', \"'greeting_flow'\", \"'node3'\")"; "('NODE', \"'greeting_flow'\", \"'node3'\")":forward -> "('NODE', \"'greeting_flow'\", \"'node4'\")"; "('NODE', \"'greeting_flow'\", \"'node4'\")":"'node1'" -> "('NODE', \"'greeting_flow'\", \"'node1'\")"; - "('NODE', \"'greeting_flow'\", \"'node4'\")":forward -> "('NODE', \"'greeting_flow'\", \"'node1'\")"; "('NODE', \"'greeting_flow'\", \"'node4'\")":to_fallback -> "('NODE', \"'global_flow'\", \"'fallback_node'\")"; - "('NODE', \"'greeting_flow'\", \"'node4'\")":repeat -> "('NODE', \"'greeting_flow'\", \"'node4'\")"; "('NODE', \"'music_flow'\", \"'node3'\")":to_fallback -> "('NODE', \"'global_flow'\", \"'fallback_node'\")"; "('NODE', \"'music_flow'\", \"'node3'\")":backward -> "('NODE', \"'music_flow'\", \"'node2'\")"; "('NODE', \"'music_flow'\", \"'node3'\")":repeat -> "('NODE', \"'music_flow'\", \"'node3'\")"; - "('NODE', \"'music_flow'\", \"'node3'\")":forward -> "('NODE', \"'music_flow'\", \"'node4'\")"; + "('NODE', \"'music_flow'\", \"'node3'\")":forward -> "('NODE', \"'music_flow'\", \"'node4'\")" [minlen=1]; "('NODE', \"'music_flow'\", \"'node4'\")":to_fallback -> "('NODE', \"'global_flow'\", \"'fallback_node'\")"; - "('NODE', \"'music_flow'\", \"'node4'\")":forward -> "('NODE', \"'music_flow'\", \"'node1'\")"; - "('NODE', \"'music_flow'\", \"'node4'\")":repeat -> "('NODE', \"'music_flow'\", \"'node4'\")"; } diff --git a/tests/viewer/opts_on.dot b/tests/viewer/opts_on.dot index 17ff0e902..116b6d7cf 100644 --- a/tests/viewer/opts_on.dot +++ b/tests/viewer/opts_on.dot @@ -22,79 +22,60 @@ digraph { label=GREETING_FLOW, style="rounded, filled" ]; - "('NODE', \"'greeting_flow'\", \"'node1'\")" [label=<



NODE1


Response

rsp.choice(['Hi, what is up?', 'Hello, how are you?'])


Misc

{"'var3'": "'info_of_step_1'"}


Transitions
(
cnd.true())
(
cnd.true())
(
cnd.regexp('how are you'))
(
cnd.all([cnd.regexp('next\\b'), cnd.has_last_labels(labels=[('music_flow', i) for i in ['node2', 'node3']])]))
(
cnd.all([cnd.regexp('repeat', re.I), cnd.negation(cnd.has_last_labels(flow_labels=['global_flow']))]))
>]; - "('NODE', \"'greeting_flow'\", \"'node2'\")" [label=<


NODE2


Response

'Good. What do you want to talk about?'


Transitions
(
cnd.regexp('talk about music'))
(
cnd.true())
(
cnd.true())
(
cnd.all([cnd.regexp('next\\b'), cnd.has_last_labels(labels=[('music_flow', i) for i in ['node2', 'node3']])]))
(
cnd.regexp('talk about'))
(
cnd.all([cnd.regexp('repeat', re.I), cnd.negation(cnd.has_last_labels(flow_labels=['global_flow']))]))
>]; - "('NODE', \"'greeting_flow'\", \"'node3'\")" [label=<


NODE3


Response

foo


Transitions
(
cnd.true())
(
cnd.all([cnd.regexp('next\\b'), cnd.has_last_labels(labels=[('music_flow', i) for i in ['node2', 'node3']])]))
(
cnd.regexp('bye'))
(
cnd.all([cnd.regexp('repeat', re.I), cnd.negation(cnd.has_last_labels(flow_labels=['global_flow']))]))
>]; - "('NODE', \"'greeting_flow'\", \"'node4'\")" [label=<


NODE4


Response

bar('bye')


Transitions
(
cnd.regexp('hi|hello', re.IGNORECASE))
(
cnd.all([cnd.regexp('next\\b'), cnd.has_last_labels(labels=[('music_flow', i) for i in ['node2', 'node3']])]))
(
cnd.true())
(
cnd.true())
(
cnd.all([cnd.regexp('repeat', re.I), cnd.negation(cnd.has_last_labels(flow_labels=['global_flow']))]))
>]; + "('NODE', \"'greeting_flow'\", \"'node1'\")" [label=<



NODE1


Response

rsp.choice(['Hi, what is up?', 'Hello, how are you?'])


Misc

{"'var3'": "'info_of_step_1'"}


Transitions
(
cnd.true())
(
cnd.regexp('how are you'))
>]; + "('NODE', \"'greeting_flow'\", \"'node2'\")" [label=<


NODE2


Response

'Good. What do you want to talk about?'


Transitions
(
cnd.regexp('talk about music'))
(
cnd.true())
(
cnd.regexp('talk about'))
>]; + "('NODE', \"'greeting_flow'\", \"'node3'\")" [label=<


NODE3


Response

foo


Transitions
(
cnd.regexp('bye'))
>]; + "('NODE', \"'greeting_flow'\", \"'node4'\")" [label=<


NODE4


Response

bar('bye')


Transitions
(
cnd.regexp('hi|hello', re.IGNORECASE))
(
cnd.true())
>]; } subgraph "cluster_'music_flow'" { graph [color="#f78378", label=MUSIC_FLOW, style="rounded, filled" ]; - "('NODE', \"'music_flow'\", \"'node1'\")" [label=<


NODE1


Response

'I love `System of a Down` group, would you like to tell about it? '


Transitions
(
cnd.true())
(
cnd.true())
(
cnd.all([cnd.regexp('next\\b'), cnd.has_last_labels(labels=[('music_flow', i) for i in ['node2', 'node3']])]))
(
cnd.regexp('yes|yep|ok', re.IGNORECASE))
(
cnd.all([cnd.regexp('repeat', re.I), cnd.negation(cnd.has_last_labels(flow_labels=['global_flow']))]))
>]; - "('NODE', \"'music_flow'\", \"'node2'\")" [label=<


NODE2


Response

'System of a Down is an Armenian-American heavy metal band formed in in 1994.'


Transitions
(
cnd.true())
(
cnd.true())
(
cnd.all([cnd.regexp('next\\b'), cnd.has_last_labels(labels=[('music_flow', i) for i in ['node2', 'node3']])]))
(
cnd.regexp('next', re.IGNORECASE))
(
cnd.all([cnd.regexp('repeat', re.I), cnd.negation(cnd.has_last_labels(flow_labels=['global_flow']))]))
(
cnd.regexp('repeat', re.IGNORECASE))
>]; - "('NODE', \"'music_flow'\", \"'node3'\")" [label=<


NODE3


Response

'The band achieved commercial success with the release of five studio albums.'


Transitions
(
cnd.true())
(
cnd.true())
(
cnd.all([cnd.regexp('next\\b'), cnd.has_last_labels(labels=[('music_flow', i) for i in ['node2', 'node3']])]))
(
cnd.regexp('next', re.IGNORECASE))
(
cnd.all([cnd.regexp('repeat', re.I), cnd.negation(cnd.has_last_labels(flow_labels=['global_flow']))]))
(
cnd.regexp('repeat', re.IGNORECASE))
(
cnd.regexp('back', re.IGNORECASE))
>]; - "('NODE', \"'music_flow'\", \"'node4'\")" [label=<


NODE4


Response

"That's all what I know"


Transitions
(
cnd.regexp('next', re.IGNORECASE))
(
cnd.regexp('next time', re.IGNORECASE))
(
cnd.true())
(
cnd.true())
(
cnd.all([cnd.regexp('next\\b'), cnd.has_last_labels(labels=[('music_flow', i) for i in ['node2', 'node3']])]))
(
cnd.all([cnd.regexp('repeat', re.I), cnd.negation(cnd.has_last_labels(flow_labels=['global_flow']))]))
>]; + "('NODE', \"'music_flow'\", \"'node1'\")" [label=<


NODE1


Response

'I love `System of a Down` group, would you like to tell about it? '


Transitions
(
cnd.regexp('yes|yep|ok', re.IGNORECASE))
(
cnd.true())
>]; + "('NODE', \"'music_flow'\", \"'node2'\")" [label=<


NODE2


Response

'System of a Down is an Armenian-American heavy metal band formed in in 1994.'


Transitions
(
cnd.regexp('next', re.IGNORECASE))
(
cnd.regexp('repeat', re.IGNORECASE))
(
cnd.true())
>]; + "('NODE', \"'music_flow'\", \"'node3'\")" [label=<


NODE3


Response

'The band achieved commercial success with the release of five studio albums.'


Transitions
(
cnd.regexp('next', re.IGNORECASE))
(
cnd.regexp('back', re.IGNORECASE))
(
cnd.regexp('repeat', re.IGNORECASE))
(
cnd.true())
>]; + "('NODE', \"'music_flow'\", \"'node4'\")" [label=<


NODE4


Response

"That's all what I know"


Transitions
(
cnd.regexp('next', re.IGNORECASE))
(
cnd.regexp('next time', re.IGNORECASE))
(
cnd.true())
>]; } subgraph "cluster_'global_flow'" { graph [color="#ff7b9c", label=GLOBAL_FLOW, style="rounded, filled" ]; - "('NODE', \"'global_flow'\", \"'fallback_node'\")" [label=<


FALLBACK_NODE


Response

'Ooops'


Transitions
(
cnd.regexp('talk about music'))
(
cnd.regexp('hi|hello', re.IGNORECASE))
(
cnd.true())
(
cnd.all([cnd.regexp('next\\b'), cnd.has_last_labels(labels=[('music_flow', i) for i in ['node2', 'node3']])]))
(
cnd.all([cnd.regexp('repeat', re.I), cnd.negation(cnd.has_last_labels(flow_labels=['global_flow']))]))
(
cnd.true())
>]; - "('NODE', \"'global_flow'\", 'LOCAL')" [label=<


LOCAL


Pre_Response_Processing

{'2': "add_prefix('l2_local')", '3': "add_prefix('l3_local')"}


Transitions
(
cnd.regexp('greetings'))
(
cnd.true())
(
cnd.all([cnd.regexp('next\\b'), cnd.has_last_labels(labels=[('music_flow', i) for i in ['node2', 'node3']])]))
(
cnd.all([cnd.regexp('repeat', re.I), cnd.negation(cnd.has_last_labels(flow_labels=['global_flow']))]))
>]; - "('NODE', \"'global_flow'\", \"'start_node'\")" [label=<


START_NODE


Response

''


Transitions
(
cnd.regexp('talk about music'))
(
cnd.regexp('hi|hello', re.IGNORECASE))
(
cnd.true())
(
cnd.true())
(
cnd.all([cnd.regexp('next\\b'), cnd.has_last_labels(labels=[('music_flow', i) for i in ['node2', 'node3']])]))
(
cnd.all([cnd.regexp('repeat', re.I), cnd.negation(cnd.has_last_labels(flow_labels=['global_flow']))]))
>]; + "('NODE', \"'global_flow'\", \"'fallback_node'\")" [label=<


FALLBACK_NODE


Response

'Ooops'


Transitions
(
cnd.regexp('talk about music'))
(
cnd.regexp('hi|hello', re.IGNORECASE))
(
cnd.true())
>]; + "('LOCAL_NODE', \"'global_flow'\", 'LOCAL')" [label=<


LOCAL


Pre_Response_Processing

{'2': "add_prefix('l2_local')", '3': "add_prefix('l3_local')"}


Transitions
(
cnd.regexp('greetings'))
>]; + "('NODE', \"'global_flow'\", \"'start_node'\")" [label=<


START_NODE


Response

''


Transitions
(
cnd.regexp('talk about music'))
(
cnd.regexp('hi|hello', re.IGNORECASE))
(
cnd.true())
>]; } "('NODE', 'virtual', 'GLOBAL')":repeat -> "('NODE', 'virtual', 'GLOBAL')"; "('NODE', 'virtual', 'GLOBAL')":"('greeting_flow', 'node1', 1.1)" -> "('NODE', \"'greeting_flow'\", \"'node1'\")"; "('NODE', 'virtual', 'GLOBAL')":"('music_flow', 'node1', 1.1)" -> "('NODE', \"'music_flow'\", \"'node1'\")"; "('NODE', 'virtual', 'GLOBAL')":to_fallback -> "('NODE', \"'global_flow'\", \"'fallback_node'\")"; "('NODE', 'virtual', 'GLOBAL')":forward -> "('NODE', \"'global_flow'\", \"'fallback_node'\")"; - "('NODE', \"'greeting_flow'\", \"'node1'\")":repeat -> "('NODE', \"'greeting_flow'\", \"'node1'\")"; "('NODE', \"'greeting_flow'\", \"'node1'\")":"('global_flow', 'fallback_node', 0.1)" -> "('NODE', \"'global_flow'\", \"'fallback_node'\")"; - "('NODE', \"'greeting_flow'\", \"'node1'\")":to_fallback -> "('NODE', \"'global_flow'\", \"'fallback_node'\")"; "('NODE', \"'greeting_flow'\", \"'node1'\")":"'node2'" -> "('NODE', \"'greeting_flow'\", \"'node2'\")"; - "('NODE', \"'greeting_flow'\", \"'node1'\")":forward -> "('NODE', \"'greeting_flow'\", \"'node2'\")"; - "('NODE', \"'music_flow'\", \"'node1'\")":repeat -> "('NODE', \"'music_flow'\", \"'node1'\")"; "('NODE', \"'music_flow'\", \"'node1'\")":to_fallback -> "('NODE', \"'global_flow'\", \"'fallback_node'\")"; "('NODE', \"'music_flow'\", \"'node1'\")":forward -> "('NODE', \"'music_flow'\", \"'node2'\")"; "('NODE', \"'global_flow'\", \"'fallback_node'\")":"('greeting_flow', 'node1')" -> "('NODE', \"'greeting_flow'\", \"'node1'\")"; "('NODE', \"'global_flow'\", \"'fallback_node'\")":"('music_flow', 'node1')" -> "('NODE', \"'music_flow'\", \"'node1'\")"; - "('NODE', \"'global_flow'\", \"'fallback_node'\")":to_fallback -> "('NODE', \"'global_flow'\", \"'fallback_node'\")"; - "('NODE', \"'global_flow'\", \"'fallback_node'\")":forward -> "('NODE', \"'global_flow'\", \"'fallback_node'\")"; "('NODE', \"'global_flow'\", \"'fallback_node'\")":repeat -> "('NODE', \"'global_flow'\", \"'fallback_node'\")"; "('NODE', \"'greeting_flow'\", \"'node2'\")":"('music_flow', 'node1')" -> "('NODE', \"'music_flow'\", \"'node1'\")"; "('NODE', \"'greeting_flow'\", \"'node2'\")":to_fallback -> "('NODE', \"'global_flow'\", \"'fallback_node'\")"; - "('NODE', \"'greeting_flow'\", \"'node2'\")":repeat -> "('NODE', \"'greeting_flow'\", \"'node2'\")"; - "('NODE', \"'greeting_flow'\", \"'node2'\")":forward -> "('NODE', \"'greeting_flow'\", \"'node3'\")"; + "('NODE', \"'greeting_flow'\", \"'node2'\")":forward -> "('NODE', \"'greeting_flow'\", \"'node3'\")" [minlen=1]; "('NODE', \"'music_flow'\", \"'node2'\")":to_fallback -> "('NODE', \"'global_flow'\", \"'fallback_node'\")"; "('NODE', \"'music_flow'\", \"'node2'\")":repeat -> "('NODE', \"'music_flow'\", \"'node2'\")"; "('NODE', \"'music_flow'\", \"'node2'\")":forward -> "('NODE', \"'music_flow'\", \"'node3'\")"; - "('NODE', \"'global_flow'\", 'LOCAL')":"('greeting_flow', 'node1')" -> "('NODE', \"'greeting_flow'\", \"'node1'\")"; - "('NODE', \"'global_flow'\", 'LOCAL')":to_fallback -> "('NODE', \"'global_flow'\", \"'fallback_node'\")"; - "('NODE', \"'global_flow'\", 'LOCAL')":repeat -> "('NODE', \"'global_flow'\", 'LOCAL')"; - "('NODE', \"'global_flow'\", 'LOCAL')":forward -> "('NODE', \"'global_flow'\", \"'start_node'\")"; + "('LOCAL_NODE', \"'global_flow'\", 'LOCAL')":"('greeting_flow', 'node1')" -> "('NODE', \"'greeting_flow'\", \"'node1'\")" [minlen=1]; "('NODE', \"'global_flow'\", \"'start_node'\")":"('greeting_flow', 'node1')" -> "('NODE', \"'greeting_flow'\", \"'node1'\")"; "('NODE', \"'global_flow'\", \"'start_node'\")":"('music_flow', 'node1')" -> "('NODE', \"'music_flow'\", \"'node1'\")"; "('NODE', \"'global_flow'\", \"'start_node'\")":"'fallback_node'" -> "('NODE', \"'global_flow'\", \"'fallback_node'\")"; - "('NODE', \"'global_flow'\", \"'start_node'\")":to_fallback -> "('NODE', \"'global_flow'\", \"'fallback_node'\")"; - "('NODE', \"'global_flow'\", \"'start_node'\")":forward -> "('NODE', \"'global_flow'\", \"'fallback_node'\")"; - "('NODE', \"'global_flow'\", \"'start_node'\")":repeat -> "('NODE', \"'global_flow'\", \"'start_node'\")"; - "('NODE', \"'greeting_flow'\", \"'node3'\")":to_fallback -> "('NODE', \"'global_flow'\", \"'fallback_node'\")"; - "('NODE', \"'greeting_flow'\", \"'node3'\")":repeat -> "('NODE', \"'greeting_flow'\", \"'node3'\")"; "('NODE', \"'greeting_flow'\", \"'node3'\")":forward -> "('NODE', \"'greeting_flow'\", \"'node4'\")"; "('NODE', \"'greeting_flow'\", \"'node4'\")":"'node1'" -> "('NODE', \"'greeting_flow'\", \"'node1'\")"; - "('NODE', \"'greeting_flow'\", \"'node4'\")":forward -> "('NODE', \"'greeting_flow'\", \"'node1'\")"; "('NODE', \"'greeting_flow'\", \"'node4'\")":to_fallback -> "('NODE', \"'global_flow'\", \"'fallback_node'\")"; - "('NODE', \"'greeting_flow'\", \"'node4'\")":repeat -> "('NODE', \"'greeting_flow'\", \"'node4'\")"; "('NODE', \"'music_flow'\", \"'node3'\")":to_fallback -> "('NODE', \"'global_flow'\", \"'fallback_node'\")"; "('NODE', \"'music_flow'\", \"'node3'\")":backward -> "('NODE', \"'music_flow'\", \"'node2'\")"; "('NODE', \"'music_flow'\", \"'node3'\")":repeat -> "('NODE', \"'music_flow'\", \"'node3'\")"; "('NODE', \"'music_flow'\", \"'node3'\")":forward -> "('NODE', \"'music_flow'\", \"'node4'\")"; - "('NODE', \"'music_flow'\", \"'node4'\")":forward -> "('NODE', \"'music_flow'\", \"'node1'\")"; "('NODE', \"'music_flow'\", \"'node4'\")":to_fallback -> "('NODE', \"'global_flow'\", \"'fallback_node'\")"; - "('NODE', \"'music_flow'\", \"'node4'\")":repeat -> "('NODE', \"'music_flow'\", \"'node4'\")"; "('NODE', \"'music_flow'\", \"'node4'\")":"transitions.greeting_flow_n2_transition" -> "('NODE', 'virtual', 'UNRESOLVED')"; "('NODE', \"'music_flow'\", \"'node4'\")":"transitions.high_priority_node_transition('greeting_flow', 'node4')" -> "('NODE', 'virtual', 'UNRESOLVED')"; }