Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add: multiple fallback tutorial #316

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
160 changes: 160 additions & 0 deletions tutorials/script/core/10_multiple_fallback_nodes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
# %% [markdown]
"""
# Core: 10. Multiple fallback nodes

This tutorial shows basics of creating a separate fallback node for every flow. In this case it is done via `LOCAL` nodes.

Let's do all the necessary imports from DFF:
"""

# %pip install dff


"""Importing all the necessary modules:"""

# %%
from dff.pipeline import Pipeline
from dff.script import TRANSITIONS, RESPONSE, Message, LOCAL
import dff.script.conditions as cnd

# %% [markdown]
"""
Let's create a script that will consist of several flows, that can be accessed through dialogue:
"""

# %%
toy_script = {
"greeting_flow": {
"start_node": {
RESPONSE: Message(),
TRANSITIONS: {
("greeting_flow", "say_hi_node"): cnd.true()
}
},

"say_hi_node": {
RESPONSE: Message(text="Hello, how can I help you?"),
TRANSITIONS: {
("authorization_flow", "response_node"): cnd.exact_match(Message(text="auth")),
NotBioWaste905 marked this conversation as resolved.
Show resolved Hide resolved
("information_flow", "response_node"): cnd.exact_match(Message(text="info"))
}
},

"fallback_node": {
RESPONSE: Message(text="Unknown Command. Try again."),
TRANSITIONS: {"say_hi_node": cnd.exact_match(Message(text="hi"))
}
}
},
"authorization_flow": {
LOCAL: {
TRANSITIONS: {
("auth_fallback_node"):
NotBioWaste905 marked this conversation as resolved.
Show resolved Hide resolved
cnd.true()
}
},
"response_node": {
RESPONSE: Message(text="Write your name, please."),
TRANSITIONS: {
("authorization_flow", "auth_password_node"):
cnd.exact_match(Message(text="admin")),
("authorization_flow", "auth_success_node"):
cnd.exact_match(Message(text="John Doe"))
}
},

"auth_success_node": {
RESPONSE: Message(text="Authentication successful."),
TRANSITIONS: {
("authorization_flow", "response_node"):
NotBioWaste905 marked this conversation as resolved.
Show resolved Hide resolved
cnd.exact_match(Message(text=""))
}
},

"auth_password_node": {
RESPONSE: Message(text="Password required. Enter your password."),
TRANSITIONS: {
("authorization_flow", "auth_success_node"):
cnd.exact_match(Message(text="123"))
}
},

"auth_fallback_node": {
RESPONSE: Message(text="User not found."),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All the nodes from this flow fallback to this node. So this node is visited not only when user is not found but also, for example, when admin password is incorrect.

TRANSITIONS: {
("authorization_flow", "response_node"):
cnd.exact_match(Message(text=""))
}
}
},

"information_flow": {
LOCAL: {
TRANSITIONS: {
("information_fallback_node"):
cnd.true()
}
},
"response_node": {
RESPONSE: Message(text="What information you would like to know?"),
TRANSITIONS: {
("information_flow", "weather_city_node"):
cnd.exact_match(Message(text="weather")),
("information_flow", "time_node"):
cnd.exact_match(Message(text="time"))
}
},
"weather_city_node": {
RESPONSE: Message(text="What city are interested in?"),
TRANSITIONS: {
("information_flow", "weather_moscow_node"):
cnd.exact_match(Message(text="Moscow")),
("information_flow", "weather_new_york_node"):
cnd.exact_match(Message(text="New York"))
}
},
"weather_moscow_node": {
RESPONSE: Message(text="It's -5 Celsius"),
TRANSITIONS: {
("response_node"): cnd.true()
NotBioWaste905 marked this conversation as resolved.
Show resolved Hide resolved
}
},
"weather_new_york_node": {
RESPONSE: Message(text="It's +14 Celsius"),
TRANSITIONS: {
("response_node"): cnd.true()
}
},
"time_node": {
RESPONSE: Message(text="It's tea time!"),
TRANSITIONS: {
("information_flow", "response_node"):
cnd.true()
}
},
"information_fallback_node": {
RESPONSE: Message(text="I don't know that information!"),
TRANSITIONS: {
("information_flow", "response_node"):
cnd.true()
}
}
}
}

# %% [markdown]
"""
As you can see, we've created specific fallback node for each individual flow using `LOCAL` node. Due to the low priority this condition will trigger automatically if no other condition in any node in the flow was triggered.
Also we defined `fallback_label` in our `Pipeline` which is being overwritten with `LOCAL` nodes in flows they defined in.

And now let's run our script:
"""
# %%
pipeline = Pipeline.from_script(
toy_script,
start_label=("greeting_flow", "start_node"),
fallback_label=("greeting_flow", "fallback_node")
)

if __name__ == "__main__":
pipeline.run()