Skip to content

Instantly share code, notes, and snippets.

@catvec
Created September 5, 2016 22:37
Show Gist options
  • Select an option

  • Save catvec/e9d3c45bfcdbe8d8127ac8685a382f85 to your computer and use it in GitHub Desktop.

Select an option

Save catvec/e9d3c45bfcdbe8d8127ac8685a382f85 to your computer and use it in GitHub Desktop.
A file explaining an idea I had for a chat bot dialog system file format
# Pound signs are considered comments
# This is a sample workflow file
# The premise is that this is a college housing workflow
#
# Follows syntax of hcl file
# configure - (required) Tell the system a little bit about the workflow, considered meta data
configure {
# id - (required) A unique programmatic name for the workflow. Used to reference workflow in code.
id "housing"
# only - Sets a condition that must be met for the current action block to evaluated
only user.prefs.on_campus_housing
# idleprompt - Text to send to the user when trying to re-engage user
idleprompt "Hey {{user.name}}! Lets get working on find you a roommate!"
}
# say - A message for Oli to send, sent in order from top to bottom of file
say "Would you prefer to live in a 2 person or 4 person dorm room?" {
# name - Casual but unique description of dialog block
# Necessary to keep track of dialog block even as it's order is changed and it's options change
name "roommate count"
# If one *must* absolutely change the name parameter a list of old names can be provided
#
# name "roommate count" {
# "buddy finder" # <-- "buddy finder" was the old name
# }
#
# However, all these names must be completely unique, there can not be a `say` block with a name and
# another `say` block with the same name in an old names list
# options - A set of options to present the user after the initial message
# list - Options type, presents options from top to bottom in a numbered list
# When mapping list values either the index or the custom key of the choice will be saved
options list {
"2 person"
"4 person"
# Retrieving a mapped value of the above would present the following choices
#
# Choice Result
# "2 person" => 1
# "4 person" => 2
#
# Notice how the result starts counting at 1, this is for ease of use for non computer science aware users
# Optionally someone could rewrite the above using custom option keys as:
#
# "2 person" "2per"
# "4 person" "4per"
# Retrieving value from map would yield:
#
# Choice Result
# "2 person" => "2per"
# "4 person" => "4per"
#
# The result will be the same after any change of the first string value (ex., "2 person"),
# however the second string must remain constant for the result to stay the same
}
# map - Store the result of the users choice of options in a specific database field
# Serialization and deserialization code determined by option type
map user.prefs.room_size
# analytics - Control over what details are recorded about dialog
# not - Disable analytics recording of detail which is normally automatically tracked
#
# Note: About userId's in analytics
# It would wildly insecure if we attached a real usedId to an analytics event.
# However having a method in which to associate multiple dialog responses as coming
# from the same person is a needed feature for proper analytics
#
# Solution: run userIds through a sha256 function before sending into analytics
#
# Planned default analytics details:
# - anonymized userId
# - response (Recommended not to track if you for some reason have a question like: "What is your Social Security Number?" <-- Never answer that :/)
# - response time
# - skippable
# - skipped (false if unskippable)
analytics not userId
# Allows other miscellaneous data to be frozen in time with the analytics event
analytics user.current_mood
# A flag set on a `say` dialog, when present the user can type "#skip" to move onto the next question
skippable
# onskip - A block of code run when the user skips
onskip {
# set - Assign a value to a given variable
set user.prefs.room_size "2per"
}
}
say "Cool! Now would you like to live on a floor with majors similar to yours?" {
name "focus group feeler"
only college.focus_floor.available
# ${a} in ${b} - This format can be used in only directives to
# determine if variable "a" is container in list "b".
only user.major in college.focus_floor.available_majors
# yesno - Presents the user with two choices: "Yes" and "No"
# When mapped:
#
# Choice Result
# "Yes" => true
# "No" => false
options yesno
map user.prefs.focus_floor
}
say "What is your favorite genera of music?" {
name "favorite music"
# fill - Option which lets the user enter in a string
# When mapped, result is escaped string entered by user
option fill
map user.prefs.music
}
say "Hold on a moment, we're working right now to find you the perfect roommate!" {
name "roommate presentation"
# datafunc - A function that resides on a core server, which can be run given the inputted data.
datafunc matchRoomate {
# say (in datafunc) - A flag that can be set on a dataFunc, makes oli say the results
say
# map (in datafunc) - A options that can be set, dictating what to store the value as
map user.prefs.matched_roommate
# parameters - A key value map passed to the function
parameters {
"roomSize" user.prefs.room_size
"focusFloor" user.prefs.focus_floor
"musicPrefs" user.prefs.music
}
}
}
# The above statement could also have been written in this manner:
#
# say "Look at that! I've found you the perfect roommate: {{user.prefs.matched_roommate}}" {
# name "roommate presentation"
#
# datafunc matchRoommate {
# map user.prefs.matched_roommate
#
# parameters {
# "roomSize" user.prefs.room_size
# "focusFloor" user.prefs.focus_floor
# "musicPrefs" user.prefs.music
# }
# }
# }
#
# This works because the entire inner block is parsed before the message is sent
# Note: datafunc directive needs some work, a more elegant solution must be
# found for RPC calls
#
# This is my current working idea for a new directive to replace datafunc
#
# This directive can be place in a "say" block or alone, either way the funtion
# will be called before a the message is sent.
#
# call "match roommate" {
# map user.prefs.matched_roommate
# }
#
# (In a "say" directive")
# say "Look at that! I've found you the perfect roommate."
# say "{{gender_word}} name is {{name}} and also loves {{user.prefs.matched_roommate.common_interest}}" {
# The above also demonstrates a new feature I thought off, the
# temporary "template" namespace. The "template" namespace is a namespace
# which clears after each block. It can be used to define variables you
# may only want for one message. Variables defined in the "template"
# namespace do not have to be qualified with anything (Not "template.gender_word" but "gender_word").
#
# call "match roommate" {
# map user.prefs.matched_roommate
# }
#
# call "gender word" {
# map template.gender_word
# }
#}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment