Last Revised: 10 January 2017
Staging Mixed-Initiative Dialogs is challenging due to the number of ways that a user could steer a potential dialog. Since dialog control flow is a complex task, we devised this system for rapid prototyping and evaluation of mixed-Initiative dialogs. Our dialog engine is capable of realizing very complex dialogs from a simple, single specification of one instance of the dialog. This project uses strategies and mnemonics from programming language theory and function programming.
<<<<<<< HEAD <a name="contents"></a>
ATTENTION SIGCSE attendees: a .pdf of the poster is also in the repository.
ATTENTION: Download the html version to fix links. Bitbucket does not allow HTML-sytle links in the readme, unfortunately.
c. Build Server
d. Build Client
a. Server Usage
b. Client Usage
Perugini, S. & Buck, J.W. (2016). A language-based model for specifying and staging mixed-initiative dialogs. In Proceedings of the Eighth ACM SIGCHI Symposium on Engineering Interactive Computing Systems, New York, NY: ACM Press.
Buck, J.W. & Perugini, S. (2016). A tool for staging mixed-initiative dialogs. In Proceedings of the Twenty-seventh Annual Modern Artificial Intelligence and Cognitive Science Conference. Alternate Link
Setup instructions for the dialog engine, server, and client. For usage of the dialog engine without the server, please see this section for developers.
Start by setting up QT on your computer. Recommend QT 5.6+
None Currently (Yay!)
Download the dialog server (and engine) repository is you have not done so. Hint: This file should be in the repository.
Open the "DialogServer.pro" file with QT creator located in the "Dialog Server" folder of the downloaded repository (this repository). You will be prompted to create a new user profile for your system so that QT can build for your system. If you are prompted to use an existing user profile, choose to create a new one.
Build and run the project. Depending on the libraries installed on your computer, you might have the option to build this project for Android or IOS in addition to desktop. This is not recommended as the server enclosed is designed to run on desktop. The client (separate repository) may be built for these additional platforms.
Download the client repository if you have not done so.
Open "chatclient2.pro" with QT creator. You will be prompted to create a new user profile for your system so that QT can build for your system. If you are prompted to use an existing user profile, choose to create a new profile instead.
Build and run the project. Depending on the libraries installed on your computer, you might have the option to build this project for Android or IOS in addition to desktop. The client should be fully supported on IOS and Android platforms thanks to Qt. For information using the client, see Running the Client. For additional help building the client, please contact Josh Buck.
This section assumes that you are already running both the server and the client but have not done anything with them. For instructions downloading, building, and running the server and the client, see Set Up.
Starting the Server. Once your project builds without error (you may have a lot of annoying warnings), run the project to open a server (in a Terminal by default). The server should prompt you for a port to launch the server. The classic port number to use is 9203 and this is the default port for the client. If 9203 is already in use, you should get a message indicating as much and will have to choose a different port.
After you have selected a port, you should see a message saying that the server has connected. You can create instances of the client and connect to your server on the chosen port. If you are on a home network, you may need to set up port forwarding if you want to connect to your server from another network other than your home network.
Starting the Dialog Engine. By default, the dialog engine is off. This means that new clients will not be prompted to process the dialog. To turn the engine on, type “/engine add \<file>” into the server console window (Terminal by default on mac) where \<file> is a valid path to a .txt file that contains your xml dialog specification. To see a full list of sever commands, type “/help”.
You should see a list of responses that belong to your dialog specified in xml. If instead your server crashes then either the file was not found at the proper location or you had an error in your dialog specification. At this time, error handling is limited and the default error handling method is abort().
If you do see a list of responses from you dialog then you are good to go! If you want to change the dialog at any time, see “/engine reload <file>” or use “/engine off” followed by “/engine add \<file>”.
Shutting down the server. To shutdown the server, simply use “/shutdown”. You will be prompted to press enter. If you do not stop the server this way and simply close the window, the server may still be running. Check if the server is still running by using “top” or a similar command line function that displays processes running and look for “DialogServer” or “ServerInstance” as the name of the process. You can use “kill” to kill a process.
“/help” - See this list of commands
“/engine add \<file>” - Generate a dialog from \<file>
“/engine reload \<file>” - Regenerate a dialog from \<file>
“/engine off” - Disable the dialog engine
“/say” - Broadcast a massage to all clients
“/safespeak off” - Broadcast anything typed into stdin
“/safespeak on” - Require "/say" to broadcast
“/shutdown” - Cleanly close the server
Starting the Client. Once your project builds without error (you may have a lot of annoying warnings), run the project to open a client gui. You should see a small window asking for a user name, port, and IP address. Choose a name and enter the IP address and port of your server. The default IP address is localhost and the default port is 9203. If you have not started a server, see server usage. When ready, click the login button.
Evaluating Dialogs. You should now see a cute window listing all available dialogs. If no dialogs appear, you need to add some using the server command "\engine add \<file>" in the server terminal window. Otherwise, select the dialog you which to evaluate first. The window will change to a simple chat window and you should automatically be prompted to begin the dialog. Answer the prompts, or try different answers as you like. Hit "Send" to send a message to the server for evaluation with the current dialog.
You can undo responses by typing either "undo" or "/undo" (one of these should work) and hitting send. Similarly, you can redo by typing either "redo" or "/redo" and hitting send. If you want to restart the dialog, you can send the message "/restart" to the dialog engine and you should be re-prompted for the first question. At any time, you can hit the "back" button to go back to the list of available dialog. Doing so also restarts the current dialog.
The dialog specification file is a simple text document with two parts. The first part is the dialog formula or formulas for generating dialogs from a collection of dialog data. The second part is a collection or collections of the dialog data, wrapped in XML but independent of how the dialog is to be evaluated.
Included with this repository is a folder called Sample Dialogs with common dialogs that can be used to get a feel for the engine, and the dialog specification syntax. The "Coffee" dialogs are a simple place to start. Here is a quick example of a short, flexible coffee dialog:
Coffee PE*(size::_any, blend::_any, cream::_any) <Dialog name="Coffee" entry_prompt="Welcome to Flyer Coffee Machine"> <Prompt name="Size" prompt="What size coffee would you like?"> <Node name="small" /> <Node name="medium" /> <Node name="large" /> </Prompt> <Prompt name="Blend" prompt="What blend of coffee would you like?"> <Node name="light" /> <Node name="dark" /> </Prompt> <Prompt name="Cream" prompt="Would you like cream in your coffee?"> <Node name="Yes" /> <Node name="No" /> </Prompt> </Dialog>
The formula design is derived from functional programming mechanics and familiarity with function programming will greatly help with understanding of this dialog formula notation. For a quick look at functional programming, take a look at the wikipedia page for the programming language [ML](https://en.wikipedia.org/wiki/ML_(programming_language)).
Standard ML Function Definition With Pattern Matching:
fun <identifier>(<pattern1>) = <expression1 | <identifier>(<pattern2>) = <expression2> | ... | <identifier>(<patternK>) = <expressionK>;
In order to create a dialog, which is a function, replace "fun" with the dialog name. The dialog is the function. Next, the \<identifier> is one of the five evaluation strategies:
- Curry (C)
- Interpret (I)
- Single Partial Evaluate' (SPE')
- Partial Evaluate * (PE*)
- Partial Function Application n (PFAn)
If you do not know what these mean, please see publications. \<pattern1> is a list of variables, which are either functions themselves (sub dialogs), or solicitation (prompt) identifiers. Repeat for more patterns in the case of dialog branches.
For now, nothing goes into \<expression1>, but this is where an action would be performed after the dialog is completed. At this time, we are only interested in completing the dialog, i.e., completing the argument list. A sample dialog formula is:
Coffee PE*(size, blend, cream)
Like ML functions, our dialog-function notation supports pattern matching, which can be used to create conditional dialogs.
the remaining portion of the specification file is the XML. There are three different XML tags: \<Dialog> \<Prompt> and \<Node>, which are really "dialog", "solicitation", and "response"". The relationship is:
- Dialogs have one or more prompts
- Prompts have one or more nodes or responses (usually at least two so the user actually has a choice but not always)
The order of prompts and nodes in the XML does not matter and there is no information about the structure of the dialog in the XML. The XML simply holds the data that will be used to generate a dialog from the formula. Sample dialog data for a short coffee dialog is:
<Dialog name="Coffee" entry_prompt="Welcome to Flyer Coffee Machine"> <Prompt name="Size" prompt="What size coffee would you like?"> <Node name="small" /> <Node name="medium" /> <Node name="large" /> </Prompt> <Prompt name="Blend" prompt="What blend of coffee would you like?"> <Node name="light" /> <Node name="dark" /> </Prompt> <Prompt name="Cream" prompt="Would you like cream in your coffee?"> <Node name="Yes" /> <Node name="No" /> </Prompt> </Dialog>
This section is intended for someone who wants to use the dialog engine designed here for their own application. The dialog engine code, isolated in the folder "Engine1.0," is opensource and free to use, although you should contact Josh. The server and client QT code, while free to use for experimenting with the engine, is not properly licensed with QT for purposes other than research and academics.
In the repository, a folder called "Engine1.0" contains the dialog engine. Of the C++ classes that make up the engine, DialogStager, Dialog, and DialogGenerator are the core components. All of the other classes merely help these three classes accomplish their goals.
The dialog generator is responsible for loading a specification file, parsing the file, and generating a dialog object. The "GetDialog()" member function will return the dialog object, which can be used to create a dialog stager.
Dialog Data Structures
For information on the dialog data structure, your best bet is to check out publications.
The dialog stager is responsible for executing the dialog with one or more clients. The stager is constructed from a dialog object and has a member function "ExecuteDialog()" which will promptly execute the turns of the dialog. Alternatively, an "Evaluate(utterance)" function exists to evaluate a single user utterance with the current dialog object.
You must contact both Josh Buck and Saverio Perugini if you are interested in contributing to this project.
Who do I talk to about the code?
Please refer any implementation questions to Josh Buck.