Behavior Rules
Behavior Rules
are very flexible in structure to cover most use cases that you will come across. Behavior Rules
are clustered in Groups
. Behavior Rules
are executed sequential within each Group
. As soon as one Behavior Rule
succeeds, all remaining Behavior Rules
in this Group
will be skipped.{
"behaviorGroups": [
{
"name": "GroupName",
"behaviorRules": [
{
"name": "RuleName",
"actions": [
"action-to-be-triggered"
],
"conditions": [
<CONDITIONS>
]
},
{
"name": "DifferentRule",
"actions": [
"another-action-to-be-triggered"
],
"conditions": [
<CONDITIONS>
]
},
<MORE_RULES>
]
}
]
}
Each
Behavior Rule
has a list of conditions
, that, depending on the condition
, might have a list of sub-conditions
. If all conditions are true, then the Behavior Rule is successful and it will trigger predefined actions.
conditions
are always children of either a Behavior Rule
or another condition
. It will always follows that same structure.
The
inputmatcher
is used to match user inputs. Not directly the real input of the user, but the meaning of it, represented by expressions
that are resolved from by the parser
.Element | Value | Description |
type | inputmatcher | |
configs | expressions | comma separated list of expressions such as:expression(value),expression2(value2), yetAnotherExpressions(anotherValue(withASubValue)) |
| occurrence | currentStep - used in case if the user said it in this conversationStep lastStep - used in case if the user said it in the previous conversationStep anyStep - used in case if the user said it in any step if this whole conversationnever - used in case if the user has never said that, including the current step |
If the user would type "hello", and the parser resolves this as expressions "
greeting(hello)
" [assuming it has been defined in one of the dictionaries], then a condition
could look as following in order to match this user input meaning:(...)
"conditions": [
{
"type": "inputmatcher",
"configs": {
"expressions": "greeting(*)",
"occurrence": "currentStep"
}
}
]
(...)
This
inputmatcher
condition
will match any expression
of type greeting, may that be "greeting(hello)
", "greeting(hi)
" or anything else. Of course, if you would want to match greeting(hello)
explicitly, you would put "greeting(hello)
" as value for the "expressions
" field.The
contextmatcher
is used to match context
data that has been handed over to EDDI alongside the user input. This is great to check certain conditions
that come from another system, such as the day time or to check the existence of user data.Element | Value | Description |
type | contextmatcher | |
configs | contextKey | The key for this context (defined when handing over context to EDDI) |
| contextType | expressions object string |
| expressions (if contextType=expressions ) | A list of comma separated expressions |
| objectKeyPath (if contextType=object)objectValue | Allows match via Jsonpath , such as "profile.username " (see: https://github.com/rest-assured/rest-assured/wiki/Usage ) Exp: contextKey : userInfo , contextValue : {"profile":{"username":"John"}} The value to be match with the extracted JsonPath value |
| string | string matching (equals ) |
(...)
"conditions": [
{
"type": "contextmatcher",
"configs": {
"contextType": "expressions",
"contextKey": "someContextName",
"expressions": "contextDataExpression(*)"
}
}
]
(...)
(...)
"conditions": [
{
"type": "contextmatcher",
"configs": {
"contextType": "object",
"contextKey": "userInfo",
"objectKeyPath": "profile.username",
"objectValue": "John"
}
}
]
(...)
(...)
"conditions": [
{
"type": "contextmatcher",
"configs": {
"contextType": "string",
"contextKey": "daytime",
"string": "night"
}
}
]
(...)
The
connector
is there to all logical OR
conditions within rules. By default all conditions are AND
conditions
, but in some cases it might be suitable to connect conditions with a logical OR
.Element | Value |
type | connector |
values | operator (either AND or OR ) |
(...)
"conditions": [
{
"type": "connector",
"configs": {
"operator": "OR"
},
"conditions": [
<any other conditions>
]
}
]
(...)
Inverts the overall outcome of the children conditions
In some cases it is more relevant if a
condition
is false
than if it is true
, this is where the negation
condition
comes into play. The logical result of all children together (AND
connected), will be inverted.Child 1 - true
Child 2 - true
→ Negation = false
Child 1 - false
Child 2 - true
→ Negation = true
(...)
"conditions": [
{
"type": "negation",
"conditions": [
<any other conditions>
]
}
]
(...)
Defines the occurrence/frequency of an action in a
Behavior Rule
.(...)
{
"type": "occurrence",
"configs": {
"maxTimesOccurred": "0",
"minTimesOccurred": "0",
"behaviorRuleName": "Welcome"
}
}
(...)
Check if another
Behavior Rule
has met it's condition or not in the same conversationStep
. Sometimes you need to know if a rule has succeeded , dependency
will take that rule that hasn't been executed yet in a sandbox environment as a reference
for an other behavior rule.(...)
{
"type": "dependency",
"configs": {
"reference": "<name-of-another-behavior-rule>"
}
}
(...)
As
inputMatcher
doesn't look at expressions but it looks for actions instead, imagine a Behavior Rule
has been triggered and you want to check if that action has been triggered before.(...)
{
"type": "actionmatcher",
"configs": {
"actions": "show_available_products",
"occurrence": "lastStep"
}
}
(...)
This will allow you to compile a condition based on any http request/properties or any sort of variables available in EDDI's context.
(...)
{
"type": "dynamicvaluematcher",
"configs": {
"valuePath": "memory.current.httpCalls.someObj.errors",
"contains": "partly matching",
"equals": "needs to be equals"
}
}
(...)
The API Endpoints below will allow you to manage the
Behavior Rule
s in your EDDI instance.The
{id}
is a path parameters that indicate which behavior rule you want to alter.HTTP Method | API Endpoint | Request Body | Response |
DELETE | /behaviorstore/behaviorsets/{id} | N/A | N/A |
GET | /behaviorstore/behaviorsets/{id} | N/A | BehaviorSet model |
PUT | /behaviorstore/behaviorsets/{id} | BehaviorSet model | N/A |
GET | /behaviorstore/behaviorsets/descriptors | N/A | BehaviorSet model |
POST | /behaviorstore/behaviorsets | BehaviorSet model | N/A |
GET | /behaviorstore/behaviorsets/{id}/currentversion | N/A | BehaviorSet model |
POST | /behaviorstore/behaviorsets/{id}/currentversion | BehaviorSet model | N/A |
We will demonstrate here the creation of a
BehaviorSet
Request URL
POST http://localhost:7070/behaviorstore/behaviorsets
Request Body
{
"behaviorGroups": [
{
"name": "Smalltalk",
"behaviorRules": [
{
"name": "Welcome",
"actions": [
"welcome"
],
"conditions": [
{
"type": "negation",
"conditions": [
{
"type": "occurrence",
"configs": {
"maxTimesOccurred": "1",
"behaviorRuleName": "Welcome"
}
}
]
}
]
},
{
"name": "Greeting",
"actions": [
"greet"
],
"conditions": [
{
"type": "inputmatcher",
"configs": {
"expressions": "greeting(*)",
"occurrence": "currentStep"
}
}
]
},
{
"name": "Goodbye",
"actions": [
"say_goodbye",
"CONVERSATION_END"
],
"conditions": [
{
"type": "inputmatcher",
"configs": {
"expressions": "goodbye(*)"
}
}
]
},
{
"name": "Thank",
"actions": [
"thank"
],
"conditions": [
{
"type": "inputmatcher",
"configs": {
"expressions": "thank(*)"
}
}
]
},
{
"name": "how are you",
"actions": [
"how_are_you"
],
"conditions": [
{
"type": "inputmatcher",
"configs": {
"expressions": "how_are_you"
}
}
]
}
]
}
]
}
Response Body
no content
Response Code
201
Response Headers
{
"access-control-allow-origin": "*",
"date": "Thu, 21 Jun 2018 01:00:02 GMT",
"access-control-allow-headers": "authorization, Content-Type",
"content-length": "0",
"location": "eddi://ai.labs.behavior/behaviorstore/behaviorsets/5b2af892ee5ee72440ee1b4b?version=1",
"access-control-allow-methods": "GET, PUT, POST, DELETE, PATCH, OPTIONS",
"access-control-expose-headers": "location",
"content-type": null
}
Last modified 2yr ago