-
Notifications
You must be signed in to change notification settings - Fork 22
Getting Started
This article presents the core concepts to define and run bots with Xatkit.
Objectives
- Learn how to design simple intents with the Xatkit language
- Learn how to design states to create a bot execution scenario
⚠ To complete this tutorial you need to have a local installation of Xatkit. You can check the installation instructions to know how to setup your Xatkit environment.
The GreetingsBot is a bot example embedded with Xatkit. You can open it in your preferred editor as a maven project by importing xatkit/xatkit-examples/GreetingsBots/GreetingsBot
.
⚠ Your editor needs to support maven projects
The imported project contains a single class com.xatkit.example.GreetingsBot
with the definition of our bot.
The first step to create a bot is define the intents it needs to react to. Our Xatkit DSL contains an intent
top-level construct to help you:
val greetings = intent("Greetings")
.trainingSentence("Hi")
.trainingSentence("Hello")
.trainingSentence("Good morning")
.trainingSentence("Good afternoon");
val howAreYou = intent("HowAreYou")
.trainingSentence("How are you?")
.trainingSentence("What's up?")
.trainingSentence("How do you feel?");
Each intent contains a list of training sentences representing examples of user inputs corresponding to the intent to match.
📚 It is also possible to extract information from user inputs but this will be detailed in a later tutorial.
Now that we have defined our intents we need to setup the platform(s) the bot will interact with, and the providers it will use to receive user inputs.
ReactPlatform reactPlatform = new ReactPlatform();
ReactEventProvider reactEventProvider = reactPlatform.getReactEventProvider();
ReactIntentProvider reactIntentProvider = reactPlatform.getReactIntentProvider();
In this example, we will deploy our bot on a webpage using our javascript widget, so we instantiate the corresponding ReactPlatform
. We also want to receive user intents from the widget, so we construct an instance of ReactIntentProvider
. Finally, we want our bot to receive events emitted by the widget (e.g. when the connection is ready) to greet the user when she opens the page. Similarly, you could deploy the bot on other platforms, e.g. on Slack.
Xatkit relies on intent recognition providers to translate user inputs into intents that can be used by the runtime component to trigger actions. To simplify its configuration, this sample bot just uses a regular expression to match your intent but you could easily configure it to use a real NLP such as DialogFlow.
We can then create the states representing the bot's execution logic. A Xatkit state contains:
- An optional body executed when entering the state: this is where we put the reactions of the bot
- A mandatory list of next() transitions that are evaluated when a new event is received and specify the next state to move to
- An optional fallback executed if the received event does not match any transition condition
The code below creates the states of our Greetings bot:
/*
* Create the states we want to use in our bot.
* <p>
* Similarly to platform/provider creation, we create the state variables first, and we specify their content
* later. This allows to define circular references between states (e.g. AwaitingQuestion -> HandleWelcome ->
* AwaitingQuestion).
* <p>
* This is not mandatory though, the important point is to have fully specified states when we build the
* final bot model.
*/
val init = state("Init");
val awaitingInput = state("AwaitingInput");
val handleWelcome = state("HandleWelcome");
val handleWhatsUp = state("HandleWhatsUp");
/*
* Specify the content of the bot states (i.e. the behavior of the bot).
* <p>
* Each state contains:
* <ul>
* <li>An optional body executed when entering the state. This body is provided as a lambda expression
* with a context parameter representing the current state of the bot.</li>
* <li>A mandatory list of next() transitions that are evaluated when a new event is received. This list
* must contain at least one transition. Transitions can be guarded with a when(...) clause, or
* automatically navigated using a direct moveTo(state) clause.</li>
* <li>An optional fallback executed when there is no navigable transition matching the received event. As
* for the body the state fallback is provided as a lambda expression with a context parameter representing
* the current state of the bot. If there is no fallback defined for a state the bot's default fallback state
* is executed instead.
* </li>
* </ul>
*/
init
.next()
/*
* We check that the received event matches the ClientReady event defined in the
* ReactEventProvider. The list of events defined in a provider is available in the provider's
* wiki page.
*/
.when(eventIs(ReactEventProvider.ClientReady)).moveTo(awaitingInput);
awaitingInput
.next()
/*
* The Xatkit DSL offers dedicated predicates (intentIs(IntentDefinition) and eventIs
* (EventDefinition) to check received intents/events.
* <p>
* You can also check a condition over the underlying bot state using the following syntax:
* <pre>
* {@code
* .when(context -> [condition manipulating the context]).moveTo(state);
* }
* </pre>
*/
.when(intentIs(greetings)).moveTo(handleWelcome)
.when(intentIs(howAreYou)).moveTo(handleWhatsUp);
handleWelcome
.body(context -> reactPlatform.reply(context, "Hi, nice to meet you!"))
.next()
/*
* A transition that is automatically navigated: in this case once we have answered the user we
* want to go back in a state where we wait for the next intent.
*/
.moveTo(awaitingInput);
handleWhatsUp
.body(context -> reactPlatform.reply(context, "I am fine and you?"))
.next()
.moveTo(awaitingInput);
We can now create the bot model that will be deployed and executed by the Xatkit engine. Our DSL offers a convenience model()
builder to help you integrate all your bot pieces:
val botModel = model()
.useEvent(greetings)
.useEvent(howAreYou)
.usePlatform(reactPlatform)
.listenTo(reactEventProvider)
.listenTo(reactIntentProvider)
.useState(awaitingInput)
.useState(handleWelcome)
.useState(handleWhatsUp)
.initState(init)
.defaultFallbackState(defaultFallback);
Note that you need to specify the init state (i.e. the state where the bots starts) as well as the default fallback state (i.e. the state that is executed if there is no fallback defined and a received event doesn't match any transition). You can skip listing the rest of states (and intents) as they are reachable from the initState and transitively added internally.
You can define a simple default fallback using the following snippet:
val defaultFallback = fallbackState()
.body(context -> reactPlatform.reply(context, "Sorry, I didn't, get it"));
Everything is ready, and we can now run our bot by calling the XatkitCore
class:
XatkitBot xatkitBot = new XatkitBot(botModel, new BaseConfiguration());
xatkitBot.run();
You can test your bot by navigating to http://localhost:5000
. This port number and many other configuration options can be modified by playing with the Configuration
object linked to the xatkitBot
.
📚 If you want to start a bot from scratch you can check our Github template repository containing a preset maven project with the Greetings bot you can easily clone and update.
- Getting Started
- Configuring your bot
- Integrating an Intent Recognition Provider
- Adding a bot to your website
- Deploying on Slack
- Basic concepts
- Intents and Entities
- States, Transitions, and Context
- Default and Local Fallbacks
- Core Library