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 1 commit
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
127 changes: 127 additions & 0 deletions tutorials/script/core/10_multiple_fallback_nodes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
# %% [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 transitions (LINK).
RLKRo marked this conversation as resolved.
Show resolved Hide resolved

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
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"): cnd.true()
}
},

"fallback_node": {
RESPONSE: Message(text="Unknown Command. Try again."),
TRANSITIONS: {"say_hi_node": cnd.exact_match(Message(text="hi"))
}
}
},
"authorization_flow": {
"response_node": {
RESPONSE: Message(text="Write your name, please."),
TRANSITIONS: {
("authorization_flow", "auth_success_node"):
cnd.exact_match(Message(text="admin")),
("authorization_fallback_node"):
cnd.true()
}
},

"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=""))
}
},

"authorization_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": {
"response_node": {
RESPONSE: Message(text="What information you would like to know?"),
TRANSITIONS: {
("information_flow", "weather_node"):
cnd.exact_match(Message(text="weather")),
("information_flow", "time_node"):
cnd.exact_match(Message(text="time")),
("information_fallback_node"):
cnd.true()
Copy link
Member

Choose a reason for hiding this comment

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

Script should be rewritten in a way that shows how using LOCAL transitions simplifies script writing process.

The current script has exactly one transition to fallback node per flow so it is not clear how using LOCAL helps.
If the script had several nodes that have to have a fallback then we could showcase that using LOCAL saves time from writing the same transitions in every node as it is suggested in the next markdown cell.

}
},
"weather_node": {
RESPONSE: Message(text="It's sunny now!"),
TRANSITIONS: {
("information_flow", "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 (e.g. `authorization_fallback_node` for `authorization_flow`). We define transition to them in response node of the flow (actually it can be defined in any node in the flow) using `("information_fallback_node"): cnd.true()`. Due to the low priority this condition will trigger automatically if no other condition was triggered.
RLKRo marked this conversation as resolved.
Show resolved Hide resolved

And now let's run our script:
"""
# %%
pipeline = Pipeline.from_script(
toy_script,
start_label=("greeting_flow", "start_node")
RLKRo marked this conversation as resolved.
Show resolved Hide resolved
)

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