In order to allow room for growth and development with trained chatbots, we should provide a defined solution for extending a trained bot's capabilities. This assumes the bot is being trained via DialogFlow, a free NLU managed service offered by Google.
A plugin should consist of the following components:
API client
Dialog parsers
config.yaml
Intents
Entities
Training materials
The API client could be an existing third party client, an official one, or a custom built client for use specifically with the plugin.
Dialog Parsers
A dialog parser is similar to a collection of middleware layers; it defines a sort of schema that your plugin will accept; it then parses it, passes it to and from DialogFlow, and finally delivery the payload back to the router.
Configuration
For configuration, I mirror my proposal of using /v1/yaml to ingest yaml files and store them in the store after processing them. When the code needs to get credentials or variables defined in the config.yaml file, it can be retrieved from the store and used as a global constant (?).
The yaml must provide, at minimum, the following information for the router:
Routes -> HandlerFunc(s) name, corresponds with API actions
Attributes -> All entities involved with the routes
Credentials in the form of upper case strings with the _ separator
Author
Website
Version
Example:
Version: v1.2.9
Website: chatops.ai
Author: Alec Cunningham
Credentials:
// These are stored, encrypted (dependent on the `store` backend)
// as KEY:VALUE pairs for retrieval when the router
// initializes its connection with the service
DATABASE_USER: Alec
DATABASE_PASS: gunter123!
SERVICE_TOKEN: fkladfj98032hbui3f8
Routes:
// We name space via the API version and plugin name
// to avoid issues with different services + same action
- /v1/jenkins/start
- /v1/jenkins/stop
- /v1/jenkins/build
- /v1/jenkins/jobs
Attributes:
// Note, any attribute values you recieve will
// be from the DialogFlow payload
ID: [start, stop, build, jobs]
BRANCH: [start, stop, jobs]
JOB_PARAM: [start, jobs]
Following the definitions from the config.yaml, the router should be a singular file named after its service, like jenkins.go. In it it need to, at minimum, fufill this interface:
As shown above, the plugin interface requires three structs:
// i.e. type Jenkins struct
type Client struct {
// plugin satisfies Plugin interface
plugin plugin.Plugin
// baseUrl is the API's base URL domain
baseUrl string
// request is a Request object that executes API calls
request *Requester
}
// APIRequest defines what a request to <plugin> API needs
type APIRequest struct {
Method string
Endpoint string
Payload io.Reader
Headers http.Header
Suffix string
}
// Requester is the one making calls
type Requester struct {
Base string
BasicAuth *BasicAuth
Client *http.Client
CACert []byte
SslVerify bool
}
// Status ties a build and a status together
type Status struct {
// The external job in question
job string
// version is either version number or can be used for build number
version int
// status follows the global constants for reporting healthchecks
status string
}
For clarification; service providers are the platforms that run the bot, while plugins are packages the router uses to enable communication with another service.
Plugin Architecture
In order to allow room for growth and development with trained chatbots, we should provide a defined solution for extending a trained bot's capabilities. This assumes the bot is being trained via DialogFlow, a free NLU managed service offered by Google.
A plugin should consist of the following components:
The API client could be an existing third party client, an official one, or a custom built client for use specifically with the plugin.
Dialog Parsers
A dialog parser is similar to a collection of middleware layers; it defines a sort of schema that your plugin will accept; it then parses it, passes it to and from DialogFlow, and finally delivery the payload back to the router.
Configuration
For configuration, I mirror my proposal of using
/v1/yaml
to ingestyaml
files and store them in thestore
after processing them. When the code needs to get credentials or variables defined in theconfig.yaml
file, it can be retrieved from thestore
and used as a global constant (?).The
yaml
must provide, at minimum, the following information for the router:HandlerFunc(s)
name, corresponds with API actions_
separatorExample:
Following the definitions from the
config.yaml
, the router should be a singular file named after its service, likejenkins.go
. In it it need to, at minimum, fufill this interface:As shown above, the plugin interface requires three structs:
Universal constants:
Service Handlers vs Plugins
For clarification; service providers are the platforms that run the bot, while plugins are packages the router uses to enable communication with another service.
Service providers include: