btnexus-integration
v1.0.6
Published
Baseline libary for blackout nexus integrations.
Downloads
4
Maintainers
Readme
Blackout Nexus hooks
|||
|---|---|
|Author|Marc Fiedler|
|Email|[email protected]|
|Latest stable version|0.6.8|
|Required nexusUi versions| >= 2.0.71 |
|Required Brocas versions| >= 1.5.3|
|State|Stable
|
License
|Copyright|License |---|---| |(c)2018 Blackout Technologies, Bremen|GPLv3|
Hooks are custom scripts that can be integrated into any point within a dialog
to access external or living data. Any information and data that is not part of
the original A.I. training falls under the category living data
.
Introduction
The nexus
by Blackout Technologies is a platform to create Digital Assistants and to connect them via the internet to multiple platforms. Those platforms can be websites, apps or even robots. The nexus
consists of two major parts, first being the btNexus
and second the nexusUi. The btNexus
is the network that connects the A.I. with the nexusUi and the chosen interfaces. The nexusUi is the user interface, that allows the user to create their own A.I.-based Digital Assistant. Those Digital Assistants can be anything, support chatbots or even robot personalities.
Every user has one or multiple nexusUi instances or short nexus instances, which means, it's their workspace. One nexusUi / nexus instance can host multiple personalities.
Prerequisites
- Node.JS / NPM installed on your PC
- Owner of a btNexus instance or a btNexus account
Example hooks
Movies Hook: https://github.com/Blackout-Technologies/movie-hook
Before you start
Hooks are Node.Js
packages and therefore need to fulfil the package requirements of the NPM
standart.
https://docs.npmjs.com/files/package.json
Hook Integration
In order to develop a hook you first need to subclass the Hook
class from this library. You need to implement the function process()
in order to be able to handle data from the dialog engine.
Prepare Training Function
During the training phase of the artificial intelligence, you will be able to hook yourself into the process of preparing training data.
During training preparations prepareTraining
is called with the following parameters:
|Parameter|Type|Description|
|---|---|---|
|phrases|Object|This is the intent that triggered the hook. This object has a name
and a confidence
field.|
|complete|Callback|This is the completion function, complete has to be called with an array parameter. The array must be a list of objects that have the following layout: {id: <phraseID>, text: <phraseText>}
|
/**
* @param {String} intent Name of the intent that is currently in use
* @param {Array} phrases Array that contains all phrasing examples for the intent that triggers this Hook.
* @param {Callback} complete Completion callback to continue dialog
*/
prepareTraining(intent, phrases, complete){
var samples [];
// go through all phrasings and find the once that we want
// to manipulate
for( var i in phrases ){
if( phrases[i].indexOf("$city") > -1 ){
samples.push(phrases[i]);
}
}
// return the samples back to the training service
complete(samples);
}
Process Function
The process()
function is the heart of the hook, it has the following parameters:
|Parameter|Type|Description|
|---|---|---|
|intent|Object|This is the intent that triggered the hook. This object has a name
and a confidence
field.|
|text|String|This string contains the original phrasing of the user|
|complete|Callback|This is the completion function, it has to be called at the end of your script in order to continue the dialog.|
Engine Variables
|Parameter|Type|Description|
|---|---|---|
|this.json|Object|contains the POST request body that the user client sent to the chatbot.|
|this.session|Object|Contains this.session.thread
that holds a record of past dialog with the user|
|this.slots|Object|Contains all slots that the system was able to extract|
// load the Hook class from this library
const Hook = require('nexus-hook').Hook;
// create your own hook as subclass of Hook
module.exports = class WeatherHook extends Hook {
/**
* @param {Object} intent Object with .name and .confidence
* @param {String} text Original phrasing of the user
* @param {Callback} complete Completion callback to continue dialog
*/
process(text, intent, entities, complete){
// since we already know the phrasing, we can ignore the
// intent and text parameter
this.request('GET', 'http://api.openweathermap.org/data/2.5/weather?q=Bremen&units=metric&appid=<ID>', {}, (resp) => {
// after the response from the request-pronise came back
// complete this hook with an answer string and optionally
// with a platform object.
complete({
answer: 'The weather in Bremen is: '+resp.weather[0].main+" with "+resp.main.temp+" degrees.",
platform: {}
});
});
}
}
Intent naming convention
Since btNexus version 2.0.61, the classifier will not only return the name of the classified intent and the extracted entities but also the name of the knowledge source this intent belongs to.
For all nexusUi versions >= 2.0.70 the intent names returned by the classifier will look like this:
knowledgeSourceName -> #intentName
In order to make it easier to filter by intent, the hook class offers a function called isIntent(intent, name)
. Use this function to check of you are filtering for the right intent.
if( this.isIntent(intent, "myWeatherIntent") ){
// do something if it is the weather hook
}else if( this.isIntent(intent, "someOtherIntent") ){
// do something else here
}else{
// fallback..
}
Build-in Request
Each hook comes with a build in request
function that you can use to communicate with REST Api's around the globe.
The prototype of the request function looks like this:
|Parameter|Type|Description|
|---|---|---|
|METHOD|String|Request Method (GET, POST, PUT, DELETE, etc.)|
|Url|String|Url the hook is supposed to query|
|Body|Object|JSON object that can be used to transport a JSON body|
|Authentication|Object|(Optional)Auth Object, it must contain username
and password
in order to work. {username: "myUsername", password: "myPassword"}
|
|Complate callback|Function|Callback function for completion. Will contain an object on success and undefined on error.|
// since we already know the phrasing, we can ignore the
// intent and text parameter
this.request('GET', 'https://your-rest-api.com/', {}, (resp) => {
// after the response from the request-pronise came back
// complete this hook with an answer string and optionally
// with a platform object.
//..
});
// request with authentication
this.request('GET', 'https://your-rest-api.com/', {},
{username: "secret", password: "swortfish"}, (resp) => {
// response
});
Completion Callback
The completion callback needs to be called at the end of what your
hook is doing. You have to transport at least an answer
string through
the completion callback. Optionally you can also add a platform
object
that can hold additional platform information like buttons, images or actions.
Example:
complete({
answer: "The cake is a lie!",
platform: {}
})
Nexus Tools
In the world of the Blackout Nexus, there are some specific standards you need to follow in order to leverage the maximum use of the nexus power. One of those are the so-called hyperReferences
. What that means is that you can utilise the hyperReference
objects to reference elements from outside of the scope of your hook. Links
, Buttons
, Carousels
, MailTos
and Dialog Buttons
are part of the current array of possible object types for a hyperReference
.
Another tool that you can utalize is the platformReactions
, these objects are designed for the platform interface that you are using, to have your personality communicate with humans. The HMI (Human Machine Interface) if you will. platformReactions
are much more complex as they transport not only context information for the HMI but can also contain telemetry, geometry or odometry data for more complex interfaces.
Hyper References
There are three ways to use hyperReferences
in your hook:
- Use a pre-defined
hyperReference
from within the nexusUi. The only thing you need is thename
of thehyperReference
inside your nexus instance.
complete({
answer: "The cake is a lie!",
platform: {
hyperReferences: [
this.getHyperReferenceNamed('Website')
]
}
})
- Create your own
hyperReference
when you need it. This allows for more flexibility since not every nexus instance will share the samehyperReferences
complete({
answer: "The cake is a lie!",
platform: {
hyperReferences: [
{type: "link", blank: true, target: 'http://www.vanschneider.com/wp-content/uploads/2017/01/cake_1200w.jpg', caption: "Get the cake"}
]
}
})
- Generate a
hyperReference
from existing resources inside of the hook. Assume you have a file in yourtemplates/
folder calledhome.hbs
complete({
answer: "The cake is a lie!",
platform: {
hyperReferences: [
this.generateHyperReferenceFor('home')
]
}
})
Platform Reactions
Platform reactions are very specific remote procedure calls from within the nexus. Therefore the only way to gain access to a platformReaction
is to load one directly from the Brocas service
.
complete({
answer: "The cake is a lie!",
platform: {
platformReactions: [
this.getPlatformReactionNamed('Wave')
]
}
})
Handling Hook resources
Each hook can come with it's own resources. JS/CSS files for the browser, Images and even HTML content. Each file must be kept in their respective folder.
[Hook]
-> index.js (must always be present)
-> package.json (must always be present)
-> tests (optional, but encouraged)
-> myFirstTest.js (optional)
-> img (optional)
-> <keep image resources here>
-> js (optional)
-> <keep JavaScript resources here>
-> css (optional)
-> <keep css resources here>
-> templates (optional)
-> <keep hbs resources here>
Using HTML Templates
Any hook can also come with it's own templates. Important to note here is that a hook template can only be of type "hbs" that follows the handlebars file type standart.
https://handlebarsjs.com
All templates need to be placed in the ./templates/
folder and all template files need to end with the .bhs
file extension.
If you want to pass on data to your template to replace the {{}}
handlebars markers, you can do so in your response function. Simply fill the object called this.templateVars
with data and the system will replace them for you.
this.templateVars = {
'movie-poster': resp.Poster,
'movie-title': resp.Title
}
Inside your template, reference your variables like so
<h3>{{movie-title}}</h3><br />
<img src="{{movie-poster}}" />
Handling Languages
If you want to provide multilingual support to your hook you can do that with the languageDict
implementation that comes with the nexus-hook
library.
Each hook has a member variable called captions
you can access it via this.captions
. You can get a language specific phrasing with the get()
function of the captions
object.
In order to have a working language dictionary, you need to create a file called languageDict.json
in the root folder of your hook.
Example languageDict File
{
"de-DE": {
"fallback": "Ich habe keine informationen zu deiner Suche gefunden",
"weatherAnswer": "Das Wetter in $city ist $weather mit $temperature grad"
},
"en-US": {
"fallback": "Sorry, I can't find anything.",
"weatherAnswer": "The weather in $city is $weather with $temperature degrees"
}
}
If the setup of the languageDict.json
was done correctly, you will be able to access any caption with the get()
function passing the name of the caption as a string.
Example Usage
this.captions.get('fallback'); // in the above example will return: "Sorry, I can't find anything." if the language is english
Testing
The integrations in the nexusUi
as of version <= 2.0.0 will not support error feedback. In order to test your hook, you can utilize the TestHook
class of the nexus-hook
library.
The TestHook
class has only one function called chat
the prototype of the chat function looks like this:
chat(text, intent, entities, complete);
You will have to pass an intent name and a text to the chat function of the TestHook
class. The response will then be returned through the complete callback.
The rest of the hook will behave exacly the same as it would, when you integrate it into the nexusUi
.
Example
// Test implementation
const Hook = require('nexus-hook').TestHook;
var myHook = new Hook("en-US");
myHook.addSlot("city", "Bremen");
// run the test hook with the test parameters
myHook.chat("whats the weather like in Bremen", "weahter_intent", [], (resp) => {
console.log(resp.answer);
});
Example Output
=== Testing Hook ===
Weather hook v0.1.0 loaded
Sorry, I can't find anything.
The weather in Köln is Clouds with $20.6 degrees
The weather in Bremen is Clouds with $18.43 degrees
The weather in Hamburg is Clouds with $18.6 degrees
Weather hook v0.1.0 loaded
Ich habe keine informationen zu deiner Suche gefunden
Das Wetter in Bremen ist Clouds mit $18.43 grad
Das Wetter in Hamburg ist Clouds mit $18.61 grad
Das Wetter in Köln ist Clouds mit $20.6 grad
btNexus is a product of Blackout Technologies, all rights reserved (https://blackout.ai/)