Session entities not recognized in Dialogflow training phrases - php

I have setup a Google Actions conversational project, with dialogflow and webhook intents served by my server in PHP.
Upon new dialogflow conversation startup, e.g. just before replying to the welcome intent, the php code is pushing some session entities to the dialogflow engine.
The dialogflow engine recognized correctly the session entity words until two weeks ago, when it suddendly stopped working (I have changed nothing in the code), and right now it's still not working.
The session entities are created with no errors (I added code to query dialogflow api and list session entitites after creation, and google is replying with all the words I send).
However the Intent does not recognize and does not fill in the entity parameters.
Here is the code I'm using to push the entities (using google dialogflow v2 library):
$names = [....array of strings....];
$parent = 'projects/inim-prova/agent/sessions/' . $sessionId;
$client = new SessionEntityTypesClient(['credentials' => $keyfile]]);
$entities = array_map(function($item) { return new Entity(['value' => $item, 'synonyms' => [$item]]); }, array_unique($names));
$entityType = new SessionEntityType([
'name' => $parent . "/entityTypes/$displayName",
'entity_override_mode' => EntityOverrideMode::ENTITY_OVERRIDE_MODE_SUPPLEMENT,
'entities' => $entities
]);
$client->createSessionEntityType($parent, $entityType);
this code runs with no exception thrown.
After a few lines I'm querying the server to see if everything is ok:
$req = $client->listSessionEntityTypes($this->webhookRequest->getSession());
foreach ($req as $element) {
Logger::log(Logger::DEV, __METHOD__, "SessionEntityType: " . $element->getName());
$entities = $element->getEntities();
foreach ($entities as $entity) {
$synonyms = [];
foreach ($entity->getSynonyms() as $synonym) $synonyms[] = $synonym;
Logger::log(Logger::DEV, __METHOD__, ">> " . $entity->getValue() . ": " . implode(', ', $synonyms));
}
}
and this is an extract from the debug log:
SessionEntityType: projects/inim-prova/agent/sessions/ABwppHHhgwxi5OGznpUtUq2D7BQrOKWB5Y5UYr20HRKI14iASKugPw2dL2VKMwfvZ193Mq_DUb2emQ/entityTypes/NomiLuoghiUscite
>> sala: sala
>> cucina: cucina
>> giardino: giardino
SessionEntityType: projects/inim-prova/agent/sessions/ABwppHHhgwxi5OGznpUtUq2D7BQrOKWB5Y5UYr20HRKI14iASKugPw2dL2VKMwfvZ193Mq_DUb2emQ/entityTypes/NomiUscite
>> luci: luci
>> irrigazione: irrigazione
>> cappa: cappa
therefore all the entities seem to be in the right place.
This is the intent training phrase:
(please note that ArticoliDeterminativi and Preposizioni are static entities which I'm ignoring).
and these are the parameters I get on webhook request when I say Accendi le luci in cucina:
'parameters' => array (
'NomiUscite.original' => '',
'Preposizioni.original' => '',
'NomiLuoghiUscite' => '',
'NomiUscite' => '',
'Preposizioni' => '',
'ArticoliDeterminativi.original' => 'le',
'NomiLuoghiUscite.original' => '',
'ArticoliDeterminativi' => 'il',
)
As you can see, NomiUscite and NomiLuoghiUscite are empty. I expect them to be luci and cucina.
I'm really clueless.

It looks like it really was a dialogflow bug, not a flaw in my code.
After a couple of week, Support guys from Google replied me telling that the issue has been resolved.
I've run again tests with no modification on code at all, and now it works.

You should add words 'uscita' and 'luogo' to the Session Entities. I can how the parameters can be empty if you annotate words that are not part of the entity.
You also can try adding 'Accendi le luci in cucina' as a Training Phrase.

Related

How to keep the conversation going with OpenAI API PHP sdk

I'm trying to keep a conversation going using the completion() method with OpenAI PHP SDK.
Prompt #1: "How Are You?"
Prompt #2: "What I asked you before?"
but the AI seems to forget what i asked before. and it reply with random answers to the second prompt.
The code i'm using for the 2 calls are these:
$call1 = $open_ai->completion([
'model' => 'text-davinci-003',
'prompt' => 'How Are You?',
]);
$call2 = $open_ai->completion([
'model' => 'text-davinci-003',
'prompt' => 'What i asked you before?',
]);
What am I missing? How can i keep the session alive between these two calls in order to make the AI remember what I asked before?
Second answer, as the first one did not answer OP's question.
Based on this OpenAI Playground Example, a 'conversation' can only be 'asked' by sending both the command to the API.
Don't think there is a way of keep the conversation going after retreiving a response.
Consider this example, were we send the following text:
The following is a conversation with an AI assistant.
Human: Hello
Human: What is 3 * 3?
AI:
Human: What did I just asked?
AI:
The response I get is:
You asked me what 3 * 3 is. The answer is 9.
Code used for this:
<?php
require __DIR__ . '/vendor/autoload.php';
use Orhanerday\OpenAi\OpenAi;
$open_ai_key = getenv('OPENAI_API_KEY');
$open_ai = new OpenAi($open_ai_key);
function ask($ai, $question, $model = 'text-davinci-003') {
$res = $ai->completion([
'model' => $model,
'prompt' => $question,
'temperature' => 0.9,
'max_tokens' => 150,
'frequency_penalty' => 0,
'presence_penalty' => 0.6,
'stop' => ["\nHuman:", "\nAI:"]
]);
try {
$json = #json_decode($res);
foreach ($json->choices as $choice) {
echo $choice->text . PHP_EOL;
}
} catch (Exception $e) {
var_dump($e);
return NULL;
}
}
$text = <<<EOL
The following is a conversation with an AI assistant.
Human: Hello
Human: What is 3 * 3?
AI:
Human: What did I just asked?
AI:
EOL;
$res = ask($open_ai, $text);
Note the stop array that, quoted from the documentation:
Up to 4 sequences where the API will stop generating further tokens. The returned text will not contain the stop sequence.
This seems to let the AI know where to 'read' and where to 'write'
If you remove that param from the request, it returns without the answer:
You asked what 3 times 3 is.
The same problem is here :( Kind of a dream to develop a relationship with AI to keep a conversation but apparently, every request triggers a new session, according to my experience you have to send a full text to AI (davinci for me now)to get what you want.
openai.api_key = key
response = openai.Completion.create(
model="text-davinci-003",
prompt="Human: Hello AI, how can we save our session to talk future? \nAI:",
temperature=0.9,
max_tokens=150,
top_p=1,
frequency_penalty=0.0,
presence_penalty=0.6,
stop=[" Human:", " AI:"]
)
Rep:
"text": " You can save the session by saving the conversation logs to a file or capturing screenshots of the conversation. Additionally, you can create an account with a chatbot service provider in order to save and continue conversations at any time."}

Testing Symfony validation with Panther

I'm testing my validations and I send wrong values in all my input :
$crawler = $this->client->getCrawler();
$form = $crawler->selectButton('Créer')->form();
$form->setValues([
'Contractor[lastName]' => str_repeat('maxLength', self::OVER_MAX_LENGTH,),
'Contractor[firstName]' => str_repeat('maxLength', self::OVER_MAX_LENGTH,),
'Contractor[email]' => str_repeat('maxLength', self::OVER_MAX_LENGTH,).'#society.com',
'Contractor[phone]' => str_repeat('0', self::UNDER_MIN_LENGTH,),
'Contractor[password][password][first]' => 'first',
'Contractor[password][password][second]' => 'second',
'Contractor[status]' => 'admin.crud.user.field.choices.boss'
]);
$this->client->submitForm('Créer');
$this->client->waitFor('.invalid-feedback');
$this->client->waitForVisibility('.invalid-feedback');
$this->client->takeScreenshot('add.png');
$totalErrors = $crawler->filter('div.invalid-feedback')->count();
$errorExpected = 5;
$this->assertNotCount($totalErrors, [$errorExpected]);
When I test I ask to wait until the errors are displayed. Then I count the number of errors and I compare. The problem is when this line is test $totalErrors = $crawler->filter('div.invalid-feedback')->count(); I've got an error which say :
Facebook\WebDriver\Exception\StaleElementReferenceException: stale element reference: element is not attached to the page document.
In the screenshot, the errors are displayed.
I really don't understand why because I asked to wait for the element to be in the DOM and I had no errors.
Any idea ?
It's possible that the Crawler instance you have has a "stale" HTML in its state. I don't know the exact internals, but what helped me with a similar case was to get a fresh crawler from the Client object:
// some actions that redraws the Client HTML
$crawler = $client->getCrawler();
$totalErrors = $crawler->filter('div.invalid-feedback')->count();

Active Collab API: How to get projects

I'm trying out the ActiveCollab API for my first time. I had to use StackOveflow to figure out how to get the API token since the docs don't tell me this.
Below is my code:
/* GET INTENT */
$url = 'https://my.activecollab.com/api/v1/external/login';
$fields = array(
'email' => "email#email.com",
'password' => "****"
);
$intent = curl_post_connector($url, $fields);
$intent = $intent->user->intent;
/* GET TOKEN */
$url = 'https://app.activecollab.com/my_app_id/api/v1/issue-token-intent';
$fields = array(
'intent' => $intent,
'client_name' => 'My App Name',
'client_vendor' => 'My Company Name'
);
$token = curl_post_connector($url, $fields);
$token = $token->token;
Everything above works and get's the token properly. What I find really weird is that I have to use API v1 to get this, and the docs on ActiveCollab's site don't mention any URL for API v5. It seems like this is the approach everything is taking here on StackOverflow.
Now with the token, I try to get my list of projects:
/* GET PROJECT */
$url = 'https://app.activecollab.com/my_app_id/api/v1/users';
$headers = array (
"X-Angie-AuthApiToken" => $token
);
$projects = curl_get_connector($url, $headers);
var_dump($projects);
But this does not work. There is no error returned - it instead returns an array of languages for some reason! I don't want to paste the massive json object here, so instead I'll link you to a photo of it: https://www.screencast.com/t/7p5JuFB4Gu
UPDATE:
When attempting to use the SDK, it works up until I try getting the token (which is just as far as I got without the SDK). I'm getting Server Error 500, and when looking at the logs, it says:
/home/working/public_html/ac/index.php(21): ActiveCollab\SDK\Authenticator\Cloud->issueToken(123456789)
#1 {main}
thrown in /home/working/public_html/ac/SDK/Authenticator/Cloud.php on line 115
This is line 115 of Cloud.php:
throw new InvalidArgumentException("Account #{$account_id} not loaded");
I honestly don't think I did anything wrong... there must be something wrong with my account ID.
Just for kicks, I commented out that line, and the error disappears and the page loads fine - except now I have no token...

Parse error using 'use' in Google Cloud

I am trying to post some form data to Google Datastore, using this documentation here and here. I am struggling with knowing how to post the form data to the datastore, but I thought I had cracked it when I got the following error.
Parse error: syntax error, unexpected 'use' (T_USE) in record-usage.php on line 23
So my question is in two parts:
how do I post data to the Datastore from my form? (the examples in the documentation seem to offer two different ways of posting to the store)
how do I fix this syntax error?
Here is my code (it's actually line 7 in the sample below):
if(isset($_POST['submit'])) {
# Includes the autoloader for libraries installed with composer
require __DIR__ . '/vendor/autoload.php';
# Imports the Google Cloud client library
use Google\Cloud\Datastore\DatastoreClient;
# Your Google Cloud Platform project ID
$projectId = 'room-usage';
# Instantiates a client
$datastore = new DatastoreClient([
'projectId' => $projectId
]);
# The kind for the new entity
$kind = 'RoomUsage';
# The name/ID for the new entity
$name = $roomname + $_POST('timestamp');
# The Cloud Datastore key for the new entity
$taskKey = $datastore->key($kind, $name);
if($_POST('countinput') == '') {
$formdata->Headcount = $_POST('countslider');
} else {
$formdata->Headcount = $_POST('countinput');
}
$formdata->Timestamp = $_POST('timestamp');
$formdata->EnteredBy = $_POST('userid');
$formdata->RoomID = $_POST('roomid');
$formdata->Activity = $_POST('activity');
$formdata->Estimate = $_POST('estimate');
$formdata->NotAudited = $_POST('notaudited');
$formdata->Reason = $_POST('reason');
function save_room_usage(DatastoreClient $datastore, $formdata) {
$RoomUsage = $datastore->RoomUsage();
$transaction->updateBatch([$formdata]);
$transaction->commit();
}
# Prepares the new entity
$task = $datastore->entity($taskKey,
['Timestamp' => $_POST('timestamp'),
'Headcount' => $formdata->Headcount,
'EnteredBy' => $_POST('userid'),
'RoomID' => $_POST('roomid'),
'Activity' => $_POST('activity'),
'Estimate' => $_POST('estimate'),
'NotAudited' => $_POST('notaudited'),
'Reason' => $_POST('reason')]);
# Saves the entity
$datastore->upsert($task);
$status = 'Saved ' . $task->key() . ': ' . $task['description'];
}
Use
You can't have use inside a function. Think of it like an import.
Instead, move it outside of the method but inside your namespace. Simplest way to get going is just move it to the top of your file.
Writing data
Looking at this code:
$transaction->updateBatch([$formdata]);
$transaction->commit();
I think you've misinterpreted the transaction documentation. In the code example it presents, it first reads entities from Datastore via a Batch Lookup, then writes them back as a batch with:
$transaction->updateBatch([$fromAccount, $toAccount]);
In that example $fromAccount and $toAccount are proper entities with keys.
In your example, you are trying to batch write just a bunch of random data. Since you are only writing one record, you should delete that code.
The second part of your code where you create an entity and then upsert it should work. If you did end up needing to write more than one entity in a transaction, it is $task that you would use in the updateBatch method rather than the raw data.

Plivo Rent a number Api not Working for me

require 'vendor/autoload.php';
use Plivo\RestAPI;
$auth_id = "My AUTH_ID";
$auth_token = "My AUTH_TOKEN";
$p = new RestAPI($auth_id, $auth_token);
$params = array(
'number' => '12512077502' # Phone number to buy
);
$response = $p->get_number($params);
print_r ($response);
It Will Give me Error Message
Array (
[status] => 404
[response] => Array (
[api_id] => 0b6214ee-aec4-11e5-ae4f-22000ac69a0d
[error] => not found
) )
See here https://www.plivo.com/docs/getting-started/phone-number-api/#rent-a-number
You seem to be using the wrong function (get_number) from the python helper library. The correct one is "buy_phone_number" function which uses PhoneNumber API.
Reference - https://github.com/plivo/plivo-python/blob/master/plivo.py#L175
I was using the Python plivo module and had the same problem.
From Plivo Support: "Use the new API: https://www.plivo.com/docs/api/number/phonenumber/#buy-number "
What I found that the the plivo module uses the wrong URL when renting a phone number. My work around is to make the call without the helper library. The following is Python code but it might help give you an idea what to do.
import requests
params = {
'number' : phone_number # Phone number to buy
}
host = 'https://api.plivo.com/v1/Account/%s/PhoneNumber/%s/' % \
(account_sid, phone_number)
r = requests.post(host, timeout=5, json=params, auth=(account_sid, auth_token))
assert r.status_code == 201, 'r.status_code=%s' % `r.status_code`
Update: The above might not be necessary after all. I just got an update from Plivo support. The new method name is buy_phone_number() instead of get_number(). That solved the problem for me. I assume the same is true for the PHP library.

Categories