Closed christophrumpel closed 8 years ago
With the /message
endpoint you get back the entities which where extracted from the message, but not an actual action suggestion.
Have a look at the converse
API on wit.ai and it's representation within wit-php. For that to work you have to use Conversation
and an ActionMapping
. These are supposed to work together with stories defined in your bot model on wit.
The converse API both extracts entities and delivers feedback on which action to execute next. E.g say
in your case.
Please make sure to use the latest master version of wit-php, since there was a bug with the converse
implementation and the git tag has not been bumped yet.
Hey, thx a lot. I will try that!
Hey, I tried it like this:
$api = new ConverseApi($this->witAIClient);
$actionMapping = new WitAIActionMapping();
$conversation = new Conversation($api, $actionMapping);
$context = $conversation->converse('session_id', $message);
$this->log->info('Debug: ', (array)$context);
What I get back as $context is this:
[2016-08-10 13:46:45] general.INFO: Debug: {"\u0000Tgallice\\Wit\\Model\\Context\u0000data":{"reference_date":"2016-08-10T13:46:43+0200"}} []
I expected to get a string back, like I would when I test the message inside the wit.ai chat console.
The session ID is a string that I define myself to let wit.ai know if this message is from the same user right?
Hello @christophrumpel ! Can you provide your WitAIActionMapping
implementation ? If you want to catch text messages you should configure the ActionMapping::say()
method to do that e.g :
class WitAIActionMapping extends ActionMapping {
private $logger;
public function __construct($logger) {
$this->logger = $logger;
}
...
public function say($sessionId, $message, Context $context, array $entities = []) {
// $message is the plain text message from wit.ai
$this->logger->info($message);
}
...
}
The context returned from Conversation::converse
is the last context at the end of the story (when wit.ai return a stop
action).
The session_id
is for a conversation session. From the doc:
The session_id is a unique ID you generate on your side to group messages from the same user request/conversation.
When you start a new conversation, you should generate a new one. You should generate a new one, even when the user is the same.
You get back the context from the last converse step (which is always from the stop implementation in your action mapping).
Let me walk you through what happens exactly. The wit.ai chat console does hide quite a bit.
Basically all the relevant stuff happens within the /converse
call, which recursively calls itself (and the wit.ai /converse
endpoint) to execute the relevant actions within your action mapping.
The message is sent to wit.ai's converse endpoint
$conversation->converse('session_id', $message)
The result of this will be mapped to a Step
object, which determines what to execute within your action mapping. This is what a response from wit might look like.
{
"type": "msg",
"msg": "It's gonna be sunny in Brussels.",
"confidence": 0.9963
}
Type msg
means that the say
action within your action mapping will called with the message string provided by wit.ai
It is up to you how you implement the say action. In my case I use Facebook's Messenger Send API to create a message and send it. Also the say action should return the (maybe modified) context.
Converse is then recursively called with that Context. Depending on your stories you might get back the following.
{
"type": "stop",
"confidence": 0.9963
}
Your actions mapping's stop method will be called and the outer call will return the Context from that stop method.
All the magic already happened within that $conversation->converse
call. Take the time and step through this and you will see that the methods follows the conversation flow described in the wit.ai docs.
@christophrumpel Also yes, the session_id should identify the conversation with a user. But note if one conversation flow has ended the session_id should change. Even if the user is the same.
@tgallice Two are better than one :-) I think now @christophrumpel has all the information he needs 👍
Hey, thx yes here it is:
<?php
namespace App;
use Tgallice\Wit\ActionMapping;
use Tgallice\Wit\Model\Context;
class WitAIActionMapping extends ActionMapping
{
/**
* @inheritdoc
*/
public function action($sessionId, $actionName, Context $context)
{
return call_user_func_array(array($this, $actionName), array($sessionId, $context));
}
/**
* @inheritdoc
*/
public function say($sessionId, $message, Context $context)
{
echo $message;
}
public function stop($sessionId, Context $context) {
// TODO: Implement stop() method.
}
public function error($sessionId, Context $context, $error = 'Unknown Error', array $stepData = []) {
// TODO: Implement error() method.
}
public function merge($sessionId, Context $context, array $entities) {
// TODO: Implement merge() method.
}
}
@hfinck no worries, yours is well more detailed than mine :) @hfinck And with this implementation nothing was displayed ?
Sorry didn't see the other messages. Will go through all of that. Thx a lot!
@christophrumpel Little side note. You should return the context from every method. Even if you have not changed it. This becomes quite important if you implement custom actions in your mapping which probably will be modifying the context. Depending on the context keys wit.ai predicts the next actions.
Thx @hfinck and @tgallice . I guess it is more clear to me. So when I send the user's message to the converse endpoint like
$context = $conversation->converse('session_id', $message);
$this->log->info('Debug Context: ', (array)$context);
Then I should get back something like that:
{
"type": "msg",
"msg": "It's gonna be sunny in Brussels.",
"confidence": 0.9963
}
and because of the msg
attribute the say
method of my action wrapper should be called automatically, correct?
So what I see in my log is this.
[2016-08-10 16:08:00] general.INFO: Debug Context: {"\u0000Tgallice\\Wit\\Model\\Context\u0000data":{"reference_date":"2016-08-10T16:07:59+0200"}} []
So I do get a context object back without any msg and my say method is not called. I got a log there to check that but it is not triggered.
Sorry I do get the log entry from the say method, I was wrong with that. So it gets in there, but there is no message.
Ah I had a bug. I now get the message inside the say method! Yes!=)
But why does my context object not look like that? Still something wrong somewhere?
{
"type": "msg",
"msg": "It's gonna be sunny in Brussels.",
"confidence": 0.9963
}
{
"type": "msg",
"msg": "It's gonna be sunny in Brussels.",
"confidence": 0.9963
}
It's not what you get back at the end. This JSON is returned from wit.ai within the ::converse method and is used to decide which action to call from your action mapping.
and because of the msg attribute the say method of my action wrapper should be called automatically, correct?
It is because of the type attribute with the value msg
.
You use echo
within your say method, right? That is writing to php://output
. Where did you intend your message should go?
@christophrumpel I have tried a basic wit.ia story. There are a lot strange behavior with there api... Sometime it's work, sometime no... The wit api is not "pure", you can have different results for the same input. It's depend on the training of your model (story). It's can be annoyng for this kind of test.
Ah ok this json is not what I get out, its just what the code is getting back from the converse call, I see!
I did log the $msg within the say method, this is how I check that. But now I get the messages :-) 👍 Thx a lot
thx @tgallice for mentioning the different outputs, I will keep that in mind when I ran in other problems. I have built a chatbot php boilerplate and I want to provide wit.ai as an option too. (https://github.com/christophrumpel/chatbot-php-boilerplate)
@tgallice Wit has increased their initial overfitting with the stories. So if you stick to the messages a 100% the result should be reproducible. But that's only good for testing ^^
@hfinck Yes you right for the improvement. But I can assure you, you don't get a 100% :).
@christophrumpel I have released a new version of the lib 0.3.1
. You will need to update your ActionMapping
class since there is a BC break, but it's include an improvement for the Conversation
class (thx @hfinck ).
@tgallice I mean if you send the exact message as in the story :) I also noticed that the reference_date in the context (which now is just useless payload) does confuse the model sometimes. It will get better once we replace it with reference_time/timezone.
thx I will try that new version @tgallice
Hey,
thx for the php sdk. I have setup a story on wit.ai and now I'm trying to get the bot's answer back to the user.
I do get back some informations but not the message the bot should response / answer.
{"msg_id":"e657f02a-0d1f-442c-93f5-3cf58238d4f9","_text":"lets play word game","entities":{"my_method":[{"confidence":1,"type":"value","value":"method-type"}]}}
Is this method not meant to get the message back as well?
Thx and greets Christoph