Wikipedia Factoid Bot (3 of 6) : Initializing the Factoid Bot connection to Watson Conversation

Anthony Stevens
IBM watsonx Assistant
4 min readJan 10, 2017

This is the 3rd of a six part series on training a bot to answer factoids. We’ll now initialize the bot’s connection to Watson Conversation.

Post 1: Intro factoid bot demo plus download and configure code
Post 2: Identify famous people as entities using Alchemy Language
Post 3: You are here
Post 4: Train a factoid bot to classify the intent of a user’s query
Post 5: Extract answers from DBpedia (Wikipedia)
Post 6: Finalize the conversation flow

Working Demo: Factoid bot running on Bluemix
Source Code: NodeJS factoid bot on Github

You already downloaded the bot’s files and configured access to the Watson services in the second post in this series.

NodeJS class relationships for factoid bot (located in ./javascript)

The ConversationUtils class defined in javascript/conversation_utils.js validates it has credentials to access Watson Conversation then waits for a user request to initialize a new conversation. WatsonUtils.addUrlPaths() tests incoming client/browser requests to determine if a context object is present in the request’s body or not.

See full code at javascript/watson_utils.jsWatsonUtils.prototype.addUrlPaths = function(app) 
{
...
if (req.body.context) {
...
}else{
internalThis.conversationUtils.initConversationService(res)
}
...
}

The absence of a context object indicates the client is requesting a new conversation so ConversationUtils.initConversationService() sends a message to Watson Conversation containing the workspace id of the desired conversation.

ConversationUtils.prototype.initConversationService = function(res) {
...
var payload = {
workspace_id: internalThis.config.conversation.workspace_id,
};
this.conversation.message(payload, function (err, message) {
...
});
...
}

You provided that workspace id in {your bot directory}/config/watson_config.json when you configured the factoid bot’s source code in the second post of this series.

Watson Conversation responds with output.text as the initial message to the user, a new conversation_id, plus other useful details such as a count of how many back-and-forths have occurred and where we are in the dialog stack (useful for debugging).

{
"intents":[],
"entities":[],
"input":{},
"output":{
"log_messages":[],
"text":[
"Hi. Ask me questions about famous people
such as their birthday, age, birthplace, or spouse."
],
"nodes_visited":["node_9_1483510113199"]
},
"context":{
"conversation_id":"c6f2cf1f-d5f4-4c47-83d8-68e3adf63dc5",
"system":{
"dialog_turn_counter":1,
"dialog_stack": [{"dialog_node":"root"}],
"dialog_request_counter":1
}
}
}

Save and Return that Context Back to Watson Conversation

If you don’t know already, the context object is your best friend. It tracks your conversation id and location in the stack, but more important, it allows you to inject and maintain state for your conversation. We’ll do in depth about this in the last post where we build the factoid bot conversation flow.

For now, just remember that you need to store this context, update it if neeced, and send it back to Watson Conversation upon every subsequent request so it knows your conversation_id as well as where we are in the conversation flow.

To avoid maintaining client-specific state in the bot, we currently pass the full context object to the client, On the client-side, public/js/api.js defines the Api class to handle all interactions with our factoid bot server so Api.sendRequest() sends the context back along with the user’s query.

function sendRequest(text, context) {
var payloadToWatson = {};
if (text) {
payloadToWatson.input = {
text: text
};
}
if (context) {
payloadToWatson.context = context;
}
...
var params = JSON.stringify(payloadToWatson);
http.send(params);
}

On the server side, ConversationUtils.processUserQuery() forwards everything to Watson Conversation.

ConversationUtils.prototype.processUserQuery(...)
{
var payload = internalThis.getDefaultConversationPayload()
payload.input = req.body.input
payload.context = req.body.context

...
}

But Wait…What Does Our Bot Initially Display to Users

If you were paying attention, you noticed that the initial response from Watson Conversation included output.text = “Hi. Ask me questions about famous people such as their birthday, age, birthplace, or spouse. Where did that come from? Open your factoid bot’s workspace in the tooling and go to the Dialog screen to view the bot’s root-level conversation flow.

Root level of the factoid bot’s dialog flow

To make the flow obvious, the factoid bot’s first dialog node tests for dialog_turn_counter==1 which signals the initiation of a new conversation. Expanding that node, we see where the output.text is being set.

Conversation initiation node for our factoid bot

Preparing to Send Our First User Query

Next we’ll train Watson Conversation to classify our user’s intents based on various queries they’ll submit about famous people.

--

--