Created
September 5, 2016 22:37
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # 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