chatops-ai / proposals

community driven proposals and discussion. Want to get involved? Open a PR, or comment on one!
http://chatops.pw/
1 stars 0 forks source link

Plugin Architecture #3

Closed moosh3 closed 6 years ago

moosh3 commented 6 years ago

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 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:

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:

type Plugin interface {
          Connect(string)      (Client, error)
          Close(string)
          HealthCheck(string)  *Status
          Trigger(string)      *Action
}

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
}

Universal constants:

// Universal statuses for plugins
const (
    STATUS_FAIL           = "FAIL"
    STATUS_ERROR          = "ERROR"
    STATUS_ABORTED        = "ABORTED"
    STATUS_REGRESSION     = "REGRESSION"
    STATUS_SUCCESS        = "SUCCESS"
    STATUS_FIXED          = "FIXED"
    STATUS_PASSED         = "PASSED"
)

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:

moosh3 commented 6 years ago

Feature Requests