-1

I am back with more questions. I am using Unity 5.5.1f1 and Watson Developer Cloud Unity SDK v0.13.0. And instead of using widgets, I am using the scripts inside of Watson/Examples/ServiceExamples/Scripts, they worked out pretty well, and I was able to get the conversation service going. However, I soon realized that with this setup, I can't seem to reach to child nodes. Please look at the conversation editor screenshot below:

conversation editor If I test this conversation online, it will turn out like this:

Watson: Hello, welcome to the paradise!
Me: Can you turn off the music please. 
Watson: Ok, let's turn off something, you can say music, ac, and lights.
Me: music
Watson: ok, turn the music off. [child node]

However, when I do this through Unity, it becomes:

Watson: Hello, welcome to the paradise!
Me: Can you turn off the music please. 
Watson: Ok, let's turn off something, you can say music, ac, and lights.
Me: music
Watson: say what? [anything_else node]

It seems the conversation only stays at the parent nodes, and does not reach the child node at all. Or maybe every message to the server resets the service? Please help!!

best,

Ghettokon
  • 63
  • 8
  • Found a similar question, http://stackoverflow.com/questions/42180038/slack-app-watson-watson-looses-intent-from-previous-message-received?rq=1 – Ghettokon Mar 21 '17 at 10:15
  • "I made a simple piece of code which stores the existing context grouped by Slack's user_id. If a context already exists for this user_id, then my app will call Watson API and append this context to the request, so Watson knows that this new User's input follows a previous one." how do we actually realize this in C# Unity? – Ghettokon Mar 21 '17 at 10:17

1 Answers1

1

In order to reach the child nodes you need to pass the context in the request. In the response there will be a context property you can pass to the next request.

Conversation m_Conversation = new Conversation();

private void SendInitalMessage(string input)
{
  if (string.IsNullOrEmpty(input))
    throw new ArgumentNullException("input");

  //  Send inital message to the service
  m_Conversation.Message(OnInitalMessage, <workspace-id>, input);
}



private void OnInitalMessage(MessageResponse resp, string customData)
{
    if (resp != null)
    {
        //  Check response here

        //  Create a message request object with the context
        MessageRequest messageRequest = new MessageRequest();
        messageRequest.InputText = <input-text>;
        messageRequest.alternate_intents = true;
        messageRequest.ContextData = resp.context; // Context of the conversation

        //  Send the second message
        SendFollowupMessage(messageRequest);
    }
    else
    {
       Debug.Log("Message Only: Failed to invoke Message();");
    }
}


private void SendFollowupMessage(MessageRequest messageRequest)
{
    if (messageRequest == null)
        throw new ArgumentNullException("messageRequest");

    m_Conversation.Message(OnFollowupMessage, <workspace-id>, messageRequest);
}


private void OnFollowupMessage(MessageResponse resp, string customData)
{
    if (resp != null)
    {
        // Check response here
    }
    else
    {
        Debug.Log("Full Request: Failed to invoke Message();");
    }
}

The context object contains the conversationID and other data for the service to keep track of where in the conversation the user is.

"context": {
    "conversation_id": "<conversation-id>",
    "system": {
        "dialog_stack": [
            {
                "dialog_node": "<dialog-node>"
            }
        ],
        "dialog_turn_counter": <turn-counter>,
        "dialog_request_counter": <request-counter>,
        "branch_exited": <branch-exited>,
        "branch_exited_reason": "<exited-reason>"
     },
     "defaultCounter": <default-counter>
}

EDIT: The data model seems to have updated. resp.context.system.dialog_stack should not be an array of strings. It should be an array of RuntimeDialogStack objects.

[fsObject]
SystemResponse
{
    public RuntimeDialogStack[] dialog_stack {get;set;}
    public int dialog_turn_counter {get;set;}
    public int dialog_request_counter {get;set;}
}

[fsObject]
public class RuntimeDialogStack 
{
    public string dialog_node {get;set;} 
    public bool invoked_subdialog {get;set;}
}

EDIT 2: Looks like I've been testing with mismatching version strings. Please try this data model and ensure the version param is 2017-02-03 in the VisualRecognition data model.

[fsObject]
SystemResponse
{
    public DialogNode[] dialog_stack {get;set;}
    public int dialog_turn_counter {get;set;}
    public int dialog_request_counter {get;set;}
}

[fsObject]
DialogNode
{
    public string dialog_node {get;set;}
    public bool invoked_subdialog {get;set;}
}
taj
  • 1,128
  • 1
  • 9
  • 23
  • Hi @taj, I realized and did the exact, but it still not working, so I did some Debugging and found out somehow my resp.context.system.dialog_stack is always empty (Length = 0). I also tried the same workplace with the TJbot code on my respberry Pi, it works the way it supposed to, so I took the dialog_stack array from there and manually written into dialog_stack before assigned to messageRequest `resp.context.system.dialog_stack = new string[] { "node_4_1489256441002" };` It works perfectly this way. So I assumed something wrong with the dialog_stack in Unity!? – Ghettokon Mar 27 '17 at 16:51
  • @Ghettokon The data model seemed to have been updated. I updated the answer - please give that a shot. – taj Mar 27 '17 at 17:57
  • I Debug.Log dialog_stack, it shows up in console as a `System.String[]`... – Ghettokon Mar 27 '17 at 22:00
  • Debugging the dialog_stack should show up as a type of string[] because that is what it's typed to in the data model. You need to change the model to use a DialogNode[] instead of a string[]. See Edit 2 above and also change the `Version` parameter to `2017-02-03` in the data model. – taj Mar 28 '17 at 14:22