Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Version: ≥5.0.x
Welcome to EDDI!
This article will help you to get started with EDDI.
You have two options to run EDDI, The most convenient way is to run EDDI with Docker. Alternatively, of course, you can run EDDI also from the source by checking out the git repository and build the project with maven using either the mvn command line or an IDE such as eclipse.
There are two ways to use Docker with EDDI, either with docker-compose or launch the container manually.
Prerequisite: You need an up and running Docker environment. (For references, see: )
Checkout the docker-compose file from Github:
Run Docker Command:
Create a shared network
Start a MongoDB instance using the MongoDB Docker image:
Start EDDI :
Java 21
Maven 3.8.4
MongoDB > 4.0
Setup a local mongodb (> v4.0)
On a terminal, under project root folder, run the following command:
Go to Browser -->
Note: If running locally inside an IDE you need lombok to be enabled (otherwise you will get compile errors complaining about missing constructors). Either download as plugin (e.g. inside Intellij) or follow instructions here [https://projectlombok.org/](https://projectlombok.org/
For production, launch standalone mongodb and then start an eddi instance as defined in the docker-compose file
For development, use
For integration testing run
or
Important for eclipse users: If you are planning to browse and build EDDI's code from eclipse, you must take in consideration that EDDI uses project Lombok, so you must add it to eclipse classpath, this can be done easily by executing this jar:
.m2\repository\org\projectlombok\lombok\1.16.26\lombok-1.16.26.jar
docker-compose updocker network create eddi-networkdocker run --name mongodb --network=eddi-network -d mongodocker run --name eddi --network=eddi-network -p 7070:7070 -d labsai/eddi./mvnw compile quarkus:dev./mvnw clean package '-Dquarkus.container-image.build=true'docker pull labsai/eddidocker-compose updocker-compose -f docker-compose.yml -f docker-compose.local.yml up./integration-tests.shdocker-compose -f docker-compose.yml -f docker-compose.local.yml -f docker-compose.testing.yml -p ci up -dPrerequisites: Up and Running instance of EDDI (see: Getting started)
In order to build a Chatbot with EDDI, you will have to create a few configuration files and POST them to the corresponding REST APIs.
A chatbot can consists of the following elements:
(Regular) Dictionary to define the inputs from the users as well as their meanings in respective categories, expressed by a expression language e.g. apple -> fruit(apple)
Behavior Rules triggering actions based on execution of behavior rules checking on certain conditions within the current conversation
eddi://ai.labs.regulardictionary/regulardictionarystore/regulardictionaries/ID?version=VERSION
eddi:// URI resources starting with this protocol are to be related with in EDDI
ai.labs.regulardictionary Type of resource
/regulardictionarystore/regulardictionaries API path
ID ID of the resources
VERSION Read-only version of the resource (each change is a new version)
Version of this resource (each update operation will create a new version of the resource)
The components of the generated bots
The Bot Father generates EDDI specific configuration in order to deploy a bot that utilises the ChatGPT API. EDDI is an middleware and therefore it enables the user to create a structured flow for parsing and manipulating user input, to be used by different chatbot APIs. The generated bots enable you to take the user input and to prepare the input to use the ChatGPT API without the need to have any knowledge of the API. This approach can be used with any chatbot engine. Therefore EDDI becomes the abstraction layer of your bot infrastructure.
In order to see the configuration necessary for a bot, we are going to open the bot manager that can be found on the dashboard.
After opening the bot manager a new tab opens that shows and overview of all currently configured bots.
Click on your created bot ("My first bot") in this example to see the bot configuration
The bot consists of different resources. These resources separate the different functions that are necessary to create a flow. The execution sequence of the packages is:
Property (eddi://ai.labs.property)
Parser (eddi://ai.labs.parser)
Behavior (eddi://ai.labs.parser)
HttpCalls (eddi://ai.labs.httpcalls)
Output (eddi://ai.labs.output)
Templating (eddi://ai.labs.templating)
When a user enters an input all resources are executed in the sequence above. After the execution of all the resources the bot output is generated. The user can then add another input, which triggers the next execution sequence to generate the next output.
This resource holds all necessary properties to be stored for usage. For the case of generated bot these are:
chatGptApi - the URL of the ChatGPT API
chatGptModel - the model of ChatGPT that should be used
chatGptToken - the API key of ChatGPT
chatGptSystemPrompt - the prompt used to configure ChatGPT
chatGptIntroPrompt - the promt that is displayed to the user on starting the conversation
This resource parses the user input. It can be configured to understand different phrases. In the example bot there is no parser configuration necessary.
This resource defines behaviors depending on user input, properties, http calls or context through behavior rules. In our example it is configured to take any input and create and action called "send_message".
This resource represents http calls to APIs. It is configured to call the ChatGPT API using the API key, whenever a user input has triggered the "send_message" action. As all user input triggers the "send_message" action, the package always calls the ChatGPT API with the user input.
It is also configured to build the output. The ChatGPT API responds with a JSON response. This is automatically parsed and the human readable output of the API is found and converted into an output. This output will be put in the chat.
All output that is not handled via ChatGPT is created in this resource. In the example bot the only output necessary is the conversation start prompt.
This is an internal resource that enables EDDI to substitute template strings with values from the conversation.



Http Connector)Output to answer the user's request based on actions triggered by behavior rules
Package to define which `LifecycleTasks` (such as the parser, behavior rules, rest api connector, output generation, ...) should be executed in order by how they are defined
Bot to define which packages should be executed in this bot
init a Chatbot:Exporting a bot is a fairly simple process, send a POST request to the following API endpoint and you will receive the location of the exported zip file on the response headers, specifically the location header.
Element
Value
Http Method
POST
API endpoint
/backup/export/{botId}?botVersion={botVersion}
{botId}
(Path parameter):String id of the bot that you wish to export.
{botVersion}
(Path parameter):Integer version of the bot.
Request URL:
http://localhost:7070/backup/export/5aaf90e29f7dd421ac3c7dd4?botVersion=1
Response Body: no content Response Code: 200 Response Headers:
Same process as exporting; send a POST request to the following API endpoint , you will receive the id of the imported bot on the response headers.
Element
Value
Http Method
POST
API endpoint
/backup/import
HTTP Content Type Header
application/zip
Request body
the zip file binary.
For the sake of simplifying things you can use Postman to upload the zip file of the exported bot just don't forget to add the http header of content type : application/zip.
Take a look at he image below to understand how can you upload the zip file in Postman:
Important: The bot will not be deployed after import you will have to deploy it yourself by using the corresponding api endpoint, please referrer to Deploying a bot.
{
"access-control-allow-origin": "*",
"date": "Mon, 19 Mar 2018 10:41:41 GMT",
"access-control-allow-headers": "authorization, Content-Type",
"content-length": "0",
"location": "http://localhost:7070/backup/export/5aaf90e29f7dd421ac3c7dd4-1.zip",
"access-control-allow-methods": "GET, PUT, POST, DELETE, PATCH, OPTIONS",
"content-type": null
}E.D.D.I exposes all kinds of internal JVM metrics as prometheus export.
These metrics are viewable here:
http://<eddi-instance>/q/metricsIn order to visualize these metrics, you can use this predefined dashboard for E.D.D.I:
Prompt & Conversation Management Middleware for Conversational AI APIs. Developed in Java, powered by Quarkus, provided with Docker, and orchestrated with Kubernetes or Openshift.
E.D.D.I (Enhanced Dialog Driven Interface) is a middleware to connect and manage LLM API bots with advanced prompt and conversation management for APIs such as OpenAI ChatGPT, Facebook Hugging Face, Anthropic Claude, Google Gemini and Ollama
Developed in Java using Quarkus, it is lean, RESTful, scalable, and cloud-native. It comes as Docker container and can be orchestrated with Kubernetes or Openshift. The Docker image has been certified by IBM/Red Hat.
Latest stable version: 5.5.1
License: Apache License 2.0
Project website:
E.D.D.I is a high performance middleware for managing conversations in AI-driven applications. It is designed to run efficiently in cloud environments such as Docker, Kubernetes, and Openshift. E.D.D.I offers seamless API integration capabilities, allowing easy connection with various conversational services or traditional REST APIs with runtime configurations. It supports the integration of multiple chatbots, even multiple versions of the same bot, for smooth upgrading and transitions.
Notable features include:
Seamless integration with conversational or traditional REST APIs
Configurable NLP and Behavior rules to orchestrate LLM involvement
Support for multiple chatbots, including multiple versions of the same bot, running concurrently
Support for Major AI API integrations via langchain4j: OpenAI, Hugging Face (text only), Claude, Gemini, Ollama (and more to come)
Technical specifications:
Resource-/REST-oriented architecture
Java Quarkus framework
JAX-RS
Dependency Injection
Prometheus integration (Metrics endpoint)
Kubernetes integration (Liveness/Readiness endpoint)
MongoDB for storing bot configurations and conversation logs
OAuth 2.0 (Keycloak) for authentication and user management
HTML, CSS, Javascript (Dashboard)
React (Basic Chat UI)
Version: ≥5.3.x
The Langchain lifecycle task (using the langchain4j library) allows EDDI to leverage the capabilities of various large language model (LLM) APIs. This task seamlessly integrates with a range of currently supported APIs, including OpenAI's ChatGPT, Hugging Face models, Anthropic Claude, Google Gemini, and Ollama, thereby facilitating advanced natural language processing within EDDI bots.
Note: To streamline the initial setup and configuration of the Langchain lifecycle task, you can utilize the "Bot Father" bot. The "Bot Father" bot guides you through the process of creating and configuring tasks, ensuring that you properly integrate the various LLM APIs. By using "Bot Father," you can quickly get your Langchain configurations up and running with ease, leveraging its intuitive interface and automated assistance to minimize errors and enhance productivity.
One of the coolest features of EDDI is it will allow you dynamically template your output based on data that you would receive from httpCalls or context information for instance, that makes EDDI's replies to user interactions richly and dynamically.
The output templating is evaluated by thymeleaf templating engine, that means you can use the majority of thymeleaf tags and expression language to define how you would like your output to be.

docker run --name mongodb -e MONGODB_DBNAME=eddi -d mongodocker run --name eddi --link mongodb:mongodb -p 7070:7070 -d labsai/eddiBasically while creating the bot you must include eddi://ai.labs.output to one of the packages that will be part of the bot.
Important: The templating feature will not work if it is included before
eddi://ai.labs.outputextension, it must be included after.
Here is how the output templating should be specified inside of a package.
Make sure the templating is defined after the output, not before.
{
"packageExtensions": [
{
"type": "eddi://ai.labs.output",
"config": {
"uri": "eddi://ai.labs.output/outputstore/outputsets/{{outputset_id}}?version=1"
}
},
{
"type": "eddi://ai.labs.templating"
}
]
}actions: Defines the actions that the lifecycle task is responsible for.
id: A unique identifier for the lifecycle task.
type: Specifies the type of API (e.g., openai, huggingface, anthropic, gemini, ollama).
description: Brief description of what the task accomplishes.
parameters: Key-value pairs for API configuration such as API keys, model identifiers, and other API-specific settings.
systemMessage: Optional message to include in the system context.
prompt: User input to override before the request to the LLM. If not set or empty, the user input will be taken
sendConversation: Boolean indicating whether to send the entire conversation or only user input (
Here’s an example of how to configure a Langchain task for various LLM APIs:
Note: Anthropic doesn't allow the first message to be from the bot, therefore includeFirstBotMessage should be set to false for anthropic api calls.
The Langchain task can be managed via specific API endpoints, facilitating easy setup, management, and operation within the EDDI ecosystem.
Read JSON Schema
Endpoint: GET /langchainstore/langchains/jsonSchema
Description: Retrieves the JSON schema for validating Langchain configurations
List Langchain Descriptors
Endpoint: GET /langchainstore/langchains/descriptors
Description: Returns a list of all Langchain configurations with optional filters
Read Langchain Configuration
Endpoint: GET /langchainstore/langchains/{id}
Description: Fetches a specific Langchain configuration by its ID
Update Langchain Configuration
Endpoint: PUT /langchainstore/langchains/{id}
Description: Updates an existing Langchain configuration
Create Langchain Configuration
Endpoint: POST /langchainstore/langchains
Description: Creates a new Langchain configuration
Duplicate Langchain Configuration
Endpoint: POST /langchainstore/langchains/{id}
Description: Duplicates an existing Langchain configuration
Delete Langchain Configuration
Endpoint: DELETE /langchainstore/langchains/{id}
Description: Deletes a specific Langchain configuration
Sure, here is the extended section for the configuration options:
The LangChain lifecycle task offers extended configuration options to fine-tune the behavior of tasks before and after they interact with LLM APIs. These configurations help in managing properties, handling responses, and controlling retries.
Below is an example configuration showcasing more advanced options such as preRequest, postResponse, and retryHttpCallInstruction.
preRequest.propertyInstructions: Defines properties to be set before making the request to the LLM API. Each instruction specifies:
name: The property name.
valueString: The value to be assigned to the property.
scope: The scope of the property (e.g., step, conversation, longTerm).
postResponse.propertyInstructions: Defines properties to be set based on the response from the LLM API. Each instruction specifies:
name: The property name.
valueString: The value to be assigned to the property.
scope: The scope of the property (e.g., step
postResponse.outputBuildInstructions: Configures how the response should be transformed into output. This is an alternative to addToOutput if you want to manipulate the llm results before adding them to the bot output. Each instruction specifies:
pathToTargetArray: The path to the array in the response where data is located.
iterationObjectName: The name of the object for iterating over the array.
postResponse.qrBuildInstructions: Configures quick replies based on the response. Each instruction specifies:
pathToTargetArray: The path to the array in the response where quick replies are located.
iterationObjectName: The name of the object for iterating over the array.
quickReplyValue: The value for the quick reply.
This extended configuration provides more control and flexibility in managing tasks and handling responses, ensuring that your LangChain tasks operate efficiently and effectively.
API Key Expiry: Ensure API keys are valid and renew them before expiry.
Model Misconfiguration: Verify model names and parameters to ensure they match those supported by the LLM provider.
Timeouts and Performance: Adjust timeout settings based on network performance and API responsiveness.
Prerequisites
Openshift 4.3+ Deployment
Block Storage (Preferable with storage class)
Installing the Operator from the RedHat Marketplace
Head to the Operator section in the Admin Overview and go to the OperatorHub
Choose which version of the EDDI Operator to use (Marketplace or normal)
Click install and leave the defaults (All Namespaces, Update Channel alpha and Approval Strategy Automatic)
Click subscribe
Using the operator
After the installation of the operator, go to the installed Operators menu point and click on the first EDDI menu on top and create a new Instance. Below is a minimal CustomResource. The storageclass_name has to be changed to the name of an existing StorageClass, the environment variable will be added as a label to the mongoDB deployment.
The operator will create a route automatically so you can access the EDDI admin panel. Per default the route will take the name of the CR. With the CR from above the route would look like this: eddi-route-$NAMESPACE.apps.ocp.example.com ($NAMESPACE will be the name of the project where the CR was created.)
How to use the godfather bot
After EDDI has started point your browser to this URL:
You should be seeing this on the page
Click on "Deploy Example Bot". This will deploy the Bot Father bot, to help you create your own bots utilizing ChatGPT.
This bot walks you through the process of creating a new bot that talks to ChatGPT. In order to create that bot, you will need to get an API key from ChatGPT. This key can be obtained here:
As soon as you have your key, click on Open and the first conversation with the Bot Father will start.
Click on "Let's get started!" to start the process.
First you need to type the name of your bot.
Next, you need to define the purpose of the bot.
Every bot needs an introduction to set the tone and the context of the bot for ChatGPT. This is the first prompt. This defines how ChatGPT is going to reply.
Now, the Bot Father needs the ChatGPT API key. Please enter the key here without any leading or trailing blanks.
Everything is now set up. When clicking on "Create the bot!" the Bot Father will create a new bot and you can start talking to it.
The new bot is deployed and by clicking on open, you can instantly talk to the bot.
{
"tasks": [
{
"actions": ["send_message"],
"id": "enhancedOpenAIQuery",
"type": "openai",
"description": "Generates text responses using OpenAI's GPT-4o model, tailored with specific response characteristics.",
"parameters": {
"apiKey": "your-openai-api-key",
"modelName": "gpt-4o",
"temperature": "0.7",
"timeout": "15000",
"logRequests": "true",
"logResponses": "true",
"systemMessage": "",
"sendConversation": "true",
"includeFirstBotMessage": "true",
"logSizeLimit": "-1",
"convertToObject": "false",
"addToOutput": "true"
}
}
]
}{
"tasks": [
{
"actions": [
"send_message"
],
"id": "huggingFaceQuery",
"type": "huggingface",
"description": "Generates text using Hugging Face's transformers.",
"parameters": {
"accessToken": "your-huggingface-access-token",
"modelId": "llama3",
"temperature": "0.7",
"timeout": "15000",
"systemMessage": "",
"prompt": "",
"sendConversation": "true",
"includeFirstBotMessage": "true",
"logSizeLimit": "-1",
"convertToObject": "false",
"addToOutput": "true"
}
}
]
}{
"tasks": [
{
"actions": ["send_message"],
"id": "anthropicQuery",
"type": "anthropic",
"description": "Generates text using Anthropic's AI model.",
"parameters": {
"apiKey": "your-anthropic-api-key",
"modelName": "Claude",
"temperature": "0.7",
"timeout": "15000",
"logRequests": "true",
"logResponses": "true",
"systemMessage": "",
"prompt": "",
"sendConversation": "true",
"includeFirstBotMessage": "false",
"logSizeLimit": "-1",
"convertToObject": "false",
"addToOutput": "true"
}
}
]
}{
"tasks": [
{
"actions": ["send_message"],
"id": "vertexGeminiQuery",
"type": "gemini",
"description": "Generates text using Vertex AI Gemini model.",
"parameters": {
"publisher": "vertex-ai",
"projectId": "your-project-id",
"modelId": "vertex-gemini-large",
"temperature": "0.7",
"timeout": "15000",
"logRequests": "true",
"logResponses": "true",
"systemMessage": "",
"prompt": "",
"sendConversation": "true",
"includeFirstBotMessage": "true",
"logSizeLimit": "-1",
"convertToObject": "false",
"addToOutput": "true"
}
}
]
}{
"tasks": [
{
"actions": ["send_message"],
"id": "ollamaQuery",
"type": "ollama",
"description": "Generates text using Ollama's language model.",
"parameters": {
"model": "ollama-v1",
"timeout": "15000",
"logRequests": "true",
"logResponses": "true",
"systemMessage": "",
"prompt": "",
"sendConversation": "true",
"includeFirstBotMessage": "true",
"logSizeLimit": "-1",
"convertToObject": "false",
"addToOutput": "true"
}
}
]
}{
"tasks": [
{
"id": "task_1",
"type": "example_type",
"description": "This is an example task description",
"actions": [
"action_1",
"action_2"
],
"preRequest": {
"propertyInstructions": [
{
"name": "exampleProperty",
"valueString": "exampleValue",
"scope": "step"
}
]
},
"postResponse": {
"propertyInstructions": [
{
"name": "exampleResponseProperty",
"valueString": "responseValue",
"scope": "conversation"
}
],
"outputBuildInstructions": [
{
"pathToTargetArray": "response.data",
"iterationObjectName": "item",
"outputType": "exampleType",
"outputValue": "exampleOutputValue"
}
],
"qrBuildInstructions": [
{
"pathToTargetArray": "response.quickReplies",
"iterationObjectName": "item",
"quickReplyValue": "exampleQuickReplyValue",
"quickReplyExpressions": "exampleExpression"
}
]
},
"parameters": {
"apiKey": "<apiKey>"
}
}
]
}apiVersion: labs.ai/v1alpha1
kind: Eddi
metadata:
name: eddi
spec:
size: 1
mongodb:
environment: prod
storageclass_name: managed-nfs-storage
storage_size: 20GtruefalsetrueincludeFirstBotMessage: Boolean indicating whether to include the first bot message in the conversation (true or false, default: true).
logSizeLimit: Limit for the size of the log (-1 for no limit).
convertToObject: Boolean indicating whether to convert the LLM response to an object (true or false, default: false). Note: For this to work, the response from your LLM needs to be in valid JSON format!
addToOutput: Boolean indicating whether the LLM output should automatically be added to the output (true or false, default: false).
conversationlongTermoutputType: The type of output to generate.
outputValue: The value to be used for output.
quickReplyExpressions: The expressions for the quick reply.

You can access to bot manager via:
Allows you to log out from the bot manager and redirects you to login page.
This is the bots view where you can see the list of all bots both deployed and non deployed bots.
You can use the text box next t o this label to enter your search criteria such as a bot name .
This is the list of all bots in this image example for brevity we showed only one bot, but most likely you will find a lot of bots (deployed and non deployed).
Name of the bot.
Version of that bot that it is deployed.
Last modification date of the entire bot resources.
Opens the chat with the bot by using the chat screen, more details later
Undeploy this bot from this EDDI instance.
Packages used in this bot
Packages view: coming soon.
The login allow connection with social Media such as GitHub or Google
Use login and password as credentials for registered users, basically you will have to go through the registration form which is pretty straightforward.









In this tutorial we will talk about importing/exporting bots, this is a very useful feature that will allow our bots to be very portable and easy to re-use in other machines/instances of EDDI and of course to backup and restore our bots and maintain them and keep them shiny.
Exporting a bot is a fairly simple process, send a POST request to the following API endpoint and you will receive the location of the exported zip file on the response headers, specifically the location header.
In this section we will explain how EDDI handles the context of a conversation and which data can be passed within the scope of a conversation.
In order to talk to EDDI within a context, a POST request shall be sent to /bots/{environment}/{botId}/{conversationId}, (same way as interacting in a normal conversation in EDDI) but this time we must provide more parameters:
outputsetFor the behavior rules, you have three possibilities (ordered by recommendation):
(Think of a form-like behavior, asking a couple of questions and sending these results somewhere.)
Have a question that is not covered? Drop us an email at [email protected], we are happy to enhance our documentation!
{
"behaviorGroups": [
{
"name": "Onboarding",
"behaviorRules": [
{
"name": "Welcome",
"actions": [
"welcome"
],
"conditions": [
{
"type": "actionmatcher",
"configs": {
"actions": "CONVERSATION_START"
}
}
]
}
]
}
]
}{
"behaviorGroups": [
{
"name": "Onboarding",
"behaviorRules": [
{
"name": "Welcome",
"actions": [
"welcome"
],
"conditions": [
{
"type": "actionmatcher",
"configs": {
"actions": "welcome",
"occurrence": "never"
}
}
]
}
]
}
]
}{
"behaviorGroups": [
{
"name": "Onboarding",
"behaviorRules": [
{
"name": "Welcome",
"actions": [
"welcome"
],
"conditions": [
{
"type": "occurrence",
"configs": {
"maxTimesOccurred": "0",
"behaviorRuleName": "Welcome"
}
}
]
}
]
}
]
}{
"outputSet": [
{
"action": "welcome",
"timesOccurred": 0,
"outputs": [
{
"valueAlternatives": [
{
"type": "text",
"text": "Some output here...",
"delay": 3000
}
]
}
],
"quickReplies": [
// quickreplies here
]
}
]
}{
"behaviorGroups": [
{
"name": "Onboarding",
"behaviorRules": [
{
"name": "Ask for Name",
"actions": [
"ask_for_name"
],
"conditions": [
{
"type": "actionmatcher",
"configs": {
"actions": "some_previous_action",
"occurrence": "lastStep"
}
}
]
}
]
}
]
}POST http://localhost:7070/backup/export/:botId?botVersion=:botVersion
botId
string
Id of the bot you wish to export
botVersion
string
Version of the bot
{
"access-control-allow-origin": "*",
"date": "Mon, 19 Mar 2018 10:41:41 GMT",
"access-control-allow-headers": "authorization, Content-Type",
"content-length": "0",
"location": "http://localhost:7070/backup/export/5aaf90e29f7dd421ac3c7dd4-1.zip",
"access-control-allow-methods": "GET, PUT, POST, DELETE, PATCH, OPTIONS"
Request URL:
http://localhost:7070/backup/export/5aaf90e29f7dd421ac3c7dd4?botVersion=1
Response Body: no content Response Code: 200 Response Headers:
Same process as exporting; send a POST request to the following API endpoint , you will receive the id of the imported bot on the response headers.
Element
Value
Http Method
POST
API endpoint
/backup/import
HTTP Content Type Header
application/zip
Request body
the zip file binary.
For the sake of simplifying things you can use Postman to upload the zip file of the exported bot just don't forget to add the http header of content type : application/zip.
Take a look at he image below to understand how can you upload the zip file in Postman:
Important: The bot will not be deployed after import you will have to deploy it yourself by using the corresponding API endpoint, please referrer to Deploying a bot.
Element
Tags
HTTP Method
POST
API endpoint
/bots/{environment}/{botId}/{conversationId}
{environment}
(Path parameter):String Deployment environment (e.g: restricted,unrestricted,test)
{botId}
(Path parameter):String Id of the bot that you wish to continue a conversation with.
{conversationId}
(Path parameter): String Id of the conversation that you wish to send the message to.
Here is an example of a JSON object of the input data:
Additional information:
We can also use http://localhost:7070/chat to test the context parameters by providing Context Type,Context Name, Context Value. see image below :
In this section we will be showcasing the semantic parser, which is a very important module of EDDI that plays the part of the engine that parses the semantics introduced in EDDI Chabot's definitions.
We will need regular dictionaries in order to store our custom words and phrases .
First, we will make a POST to /regulardictionarystore/regulardictionaries with a JSON in the body like this:
The API should return with 201 with a URI referencing the newly created dictionary :
eddi://ai.labs.regulardictionary/regulardictionarystore/regulardictionaries/<UNIQUE_ID>?version=<VERSION>
This URI will be used in the parser configuration.
The next step is to create a parser configuration, including the reference to the previously created dictionary .
A POST to /parserstore/parsers must be performed.
Submit this type of JSON
Important: Don't forget to replace the
<UNIQUE_ID>and<VERSION>!
In order to use the parser based on the created configurations, we will have to make a POST to /parser/<PARSER_ID>?version=<VERSION>
In the body just put plain text, it is what you would like to be parsed.
The parser will return expressions representing the elements from your plain text
Note: Keep in mind that this parser is made for human dialog, not parsing (
full-text) documents.
Output Configurations are rather simple as they contain prepared sentences that the Chatbot should reply to the user (depending on the actions coming from the Behavior Rules).
Simple Output Configuration looks like this:
The configuration contains an array of outputSet, which can contain one or more output objects.
The minimum amount of values that you need to provide in order be functional are action and outputs.
{
"access-control-allow-origin": "*",
"date": "Mon, 19 Mar 2018 10:41:41 GMT",
"access-control-allow-headers": "authorization, Content-Type",
"content-length": "0",
"location": "http://localhost:7070/backup/export/5aaf90e29f7dd421ac3c7dd4-1.zip",
"access-control-allow-methods": "GET, PUT, POST, DELETE, PATCH, OPTIONS",
"content-type": null
}{
"input": "",
"context": {
"onboardingOfUser": {
"type": "string",
"value": "true"
},
"userInfo": {
"type": "object",
"value": {
"username": "Barbara"
}
}
}
}{
"language": "en",
"words": [
{
"word": "hello",
"expressions": "greeting(hello)",
"frequency": 0
}
],
"phrases": [
{
"phrase": "good afternoon",
"expressions": "greeting(good_afternoon),language(english)"
}
]
}Matches an email address with regex (\b[A-Z0-9._%+-]+@[A-Z0-9.-]+.[A-Z]{2,4}\b)
Time
eddi://ai.labs.parser.dictionaries.time
Matches the following time formats: e.g : 01:20 , 01h20 , 22:40 , 13:43:23
Number
eddi://ai.labs.parser.dictionaries.ordinalNumber
Ordinal numbers in English language such as 1st, 2nd, 3rd, 4th, 5th, ...
Regular
eddi://ai.labs.parser.dictionaries.regular
URI to a regular dictionary resource: eddi://ai.labs.regulardictionary/regulardictionarystore/regulardictionaries/<UNIQUE_ID>version <VERSION>
Type
EDDI URI
Description
Integer
eddi://ai.labs.parser.dictionaries.integer
Matches all positive integers
Decimal
eddi://ai.labs.parser.dictionaries.decimal
Matches decimal numbers with . as well as , as a fractional separator
Punctuation
eddi://ai.labs.parser.dictionaries.punctuation
Matches common punctuation:
!(exclamation_mark)
? (question_mark)
. (dot)
, (comma)
: (colon)
; (semicolon)
eddi://ai.labs.parser.dictionaries.email
{
"extensions": {
"dictionaries": [
{
"type": "eddi://ai.labs.parser.dictionaries.integer"
},
{
"type": "eddi://ai.labs.parser.dictionaries.decimal"
},
{
"type": "eddi://ai.labs.parser.dictionaries.punctuation"
},
{
"type": "eddi://ai.labs.parser.dictionaries.email"
},
{
"type": "eddi://ai.labs.parser.dictionaries.time"
},
{
"type": " eddi://ai.labs.parser.dictionaries.ordinalNumber"
},
{
"type": "eddi://ai.labs.parser.dictionaries.regular",
"config": {
"uri": "eddi://ai.labs.regulardictionary/regulardictionarystore/regulardictionaries/<UNIQUE_ID>?version=<VERSION>"
}
}
],
"corrections": [
{
"type": "eddi://ai.labs.parser.corrections.stemming",
"config": {
"language": "english",
"lookupIfKnown": "false"
}
},
{
"type": "eddi://ai.labs.parser.corrections.levenshtein",
"config": {
"distance": "2"
}
},
{
"type": "eddi://ai.labs.parser.corrections.mergedTerms"
}
]
},
"config": null
}Now let's look at a more complex output configuration file:
Key
Description
action
This will be the "actions" coming from the Behavior Rules. If a rule succeeds, the defined action will be stored in the conversation memory.
outputs
This array of output objects are the outputs that will be replied back to the user in case the action matched the action key. You can define multiple output objects, which represent separate chat bubbles on the client side. If more than one valueAlternatives is defined, one will be picked randomly. If this output will be triggered again in a future conversationStep, then another output of this array will be favored in order to avoid repetition. (If all available outputs have been selected, it is randomized again like in the beginning). The type is mainly there to be able to distinguish the type of output on the client side (e.g. image, video
quickReplies
This is an array of QuickReply objects. Each object must contain a value, which is the text that should be displayed to the user (e.g. as button) in the conversation flow. The expressions is optional, you can define one or more comma separated expressions that define the meaning of this QuickReply. Those expressions will be temporarily taken into account in the semantic parser in the next conversationStep. So if a user chooses one of the quick replies, the parser would recognize them (even if not defined in any of the dictionaries explicitly) and resolve them with the expressions
timesOccurred
How often this action should have occurred within that conversation in order to be selected as output to the user (thus, if value of 1, it would be chosen if the action occurs for the second time)
returnDetailed (Optional)
(Query parameter):Boolean - Default : false Will return all sub results of the entire conversation steps, otherwise only public ones such as input, action, output & quickReplies.
returnCurrentStepOnly (Optional)
(Query parameter):Boolean - Default : true Will return only the latest conversationStep that has just been processed, otherwise returns all conversationSteps since the beginning of this conversation.
Request Body
a JSON object sent in the request body consists of the usual input text (message to the bot) only this time we are going to provide context information through a key value data structure ; the Context value must have one of the following : string,object or expressions.
In this section we will discuss the deployment management of Chatbots which consists of deployment/undeployment, checking status of deployment and list all the deployed Chatbots.
After all the resources required of the chatbot has been well created and configured ( Dictionary ,Behavior Rules,Output,Package,etc..) and the Chatbot is created through a POST to the API endpoint /botstore/bots, the deployment management of the Chatbots is offered by EDDI is key to have granular control over the deployed bots.
The deployment of a specific chatbot is done through a POST to /administration/{environment}/deploy/{botId}
Request URL:
http://localhost:7070/administration/unrestricted/deploy/5aaf98e19f7dd421ac3c7de9?version=1&autoDeploy=true
Response Body:
no content
Response Code:
202
Response Headers:
The undeployment of a specific chatbot is done through a POST to /administration/{environment}/undeploy/{botId}
Undeploy a chatbot
Request URL
http://localhost:7070/administration/unrestricted/undeploy/5aaf98e19f7dd421ac3c7de9?version=1
Response Body
no content
Response Code
202
Response Headers
Check the deployment status of a bot is done through a GET to /administration/{environment}/deploymentstatus/{botId}
Deployment status of a Chatbot REST API Endpoint
Request URL
http://localhost:7070/administration/unrestricted/deploymentstatus/5aaf98e19f7dd421ac3c7de9?version=1
Response Body
READY
Response Code
200
Response Headers
To list all the deployed Chabots a GET to /administration/{environment}/deploymentstore/{botId}:
Request URL
http://localhost:7070/deploymentstore/deployments
Response Code
200
Response Body
Response Headers
This guide provides step-by-step instructions to set up EDDI on Amazon ECS and connect it to a MongoDB Atlas cluster.
AWS Account: Ensure you have an AWS account with the necessary permissions to create ECS clusters, task definitions, and IAM roles
MongoDB Atlas Account: Create an account on if you don't have one
Sign Up / Log In:
Go to and log in
Create a New Cluster:
Click "Build a Cluster"
Add Database User:
Navigate to "Database Access" under the "Security" tab
Click "Add New Database User"
Create a user with the required roles and note the username and password
Network Access:
Navigate to "Network Access" under the "Security" tab
Click "Add IP Address"
Add the IP addresses that need access, including your local machine and ECS IP range
Navigate to ECS:
Go to the Amazon ECS console
Click "Task Definitions" and then "Create new Task Definition"
Select "FARGATE" as the launch type
Create Cluster:
Navigate to "Clusters" and click "Create Cluster"
Choose "Networking only" (Fargate) and follow the prompts
Create Service:
Go to "Services" and click "Create"
Select your cluster and task definition
Configure the service with the desired number of tasks and networking settings
Modify Application Configuration:
Ensure that your EDDI application uses the MongoDB connection string from the environment variables
Update any necessary configuration files
Deploy the Application:
Encryption:
Use TLS/SSL for encrypted connections (ssl=true in the connection string)
IAM Roles:
By following these steps, you can set up EDDI on Amazon ECS and connect it to MongoDB Atlas securely and efficiently. If you encounter any issues or have further questions, please refer to the AWS and MongoDB Atlas documentation or contact support.
{
"outputSet": [
{
"action": "welcome",
"outputs": [
{
"valueAlternatives": [
{
"type": "text",
"text": "Welcome! I am E.D.D.I."
}
]
}
]
}
]
}{
"outputSet": [
{
"action": "welcome",
"timesOccurred": 0,
"outputs": [
{
"valueAlternatives": [
{
"type": "text",
"text": "Welcome!"
}
]
},
{
"valueAlternatives": [
{
"type": "text",
"text": "I am E.D.D.I. How are you doing today?"
}
]
}
],
"quickReplies": [
{
"value": "I am fine",
"expressions": "feeling(fine)"
},
{
"value": "not so good",
"expressions": "feeling(not_good)"
}
]
},
{
"action": "greet",
"timesOccurred": 0,
"outputs": [
{
"valueAlternatives": [
{
"type": "text",
"text": "Hi there! Nice to meet up! :-)"
},
{
"type": "text",
"text": "Hello you! It is a pleasure meeting you.. :-)"
}
]
}
]
},
{
"action": "greet",
"timesOccurred": 1,
"outputs": [
{
"valueAlternatives": [
{
"type": "text",
"text": "Did we already say hi ?! Well, twice is better than not at all! ;-)"
},
{
"type": "text",
"text": "I like it if people are polite and greet twice, rather than not at all ;-)"
}
]
}
]
},
{
"action": "say_goodbye",
"outputs": [
{
"valueAlternatives": [
{
"type": "text",
"text": "See you soon!"
}
]
}
]
}
]
}audioElement
Value
HTTP Method
POST
API endpoint
/administration/{environment}/deploy/{botId}
{environment}
(Path parameter):String deployment environment (e.g: restricted,unrestricted,test)
{botId}
(Path parameter):String id of the bot that you wish to deploy.
Element
Value
HTTP Method
POST
API endpoint
/administration/{environment}/undeploy/{botId}
{environment}
(Path parameter):String deployment environment (e.g: restricted,unrestricted,test)
{botId}
(Path parameter):String id of the bot that you wish to undeploy.
Element
Value
HTTP Method
GET
Api endpoint
/administration/{environment}/deploymentstatus/{botId}
{environment}
(Path parameter):String deployment environment (e.g: restricted,unrestricted,test)
{botId}
(Path parameter):String id of the bot that you wish to check its deployment status.
Response
NOT_FOUND, IN_PROGRESS, ERROR and READY.
Element
Value
HTTP Method
GET
API endpoint
/deploymentstore/deployments
Choose AWS as the cloud provider and select a region
Choose the free tier (for development) or an appropriate plan for production purposes
Click "Create Cluster"
Configure Cluster:
After the cluster is created, click on "Connect"
Select "Connect Your Application"
Copy the connection string (e.g., mongodb+srv://<user>:<password>@<host>/eddi?retryWrites=true&w=majority -Dmongodb.database=eddi)
Configure Task Definition:
Use the following JSON configuration:
Deploy your EDDI application to ECS using the service created
Test the Connection:
Verify that the application connects to MongoDB Atlas by checking application logs and MongoDB Atlas metrics
Network Configuration:
Place ECS tasks in private subnets and use a NAT gateway for internet access
Configure security groups for ECS tasks and MongoDB Atlas
{
"access-control-allow-origin": "*",
"date": "Mon, 19 Mar 2018 16:32:58 GMT",
"access-control-allow-headers": "authorization, Content-Type",
"content-length": "0",
"access-control-allow-methods": "GET, PUT, POST, DELETE, PATCH, OPTIONS",
"content-type": null
}{
"access-control-allow-origin": "*",
"date": "Mon, 19 Mar 2018 16:38:36 GMT",
"access-control-allow-headers": "authorization, Content-Type",
"content-length": "0",
"access-control-allow-methods": "GET, PUT, POST, DELETE, PATCH, OPTIONS",
"content-type": null
}{
"access-control-allow-origin": "*",
"date": "Mon, 19 Mar 2018 16:33:08 GMT",
"access-control-allow-headers": "authorization, Content-Type",
"content-length": "5",
"access-control-allow-methods": "GET, PUT, POST, DELETE, PATCH, OPTIONS",
"content-type": "text/plain;charset=utf-8"
}[
{
"botId": "5aaf90e29f7dd421ac3c7dd4",
"botVersion": 1,
"environment": "unrestricted",
"deploymentStatus": "deployed"
},
{
"botId": "5aaf90e29f7dd421ac3c7dd4",
"botVersion": 1,
"environment": "restricted",
"deploymentStatus": "deployed"
},
{
"botId": "5aaf98e19f7dd421ac3c7de9",
"botVersion": 1,
"environment": "unrestricted",
"deploymentStatus": "deployed"
}
]{
"access-control-allow-origin": "*",
"date": "Mon, 19 Mar 2018 16:33:29 GMT",
"access-control-allow-headers": "authorization, Content-Type",
"content-length": "414",
"access-control-allow-methods": "GET, PUT, POST, DELETE, PATCH, OPTIONS",
"content-type": "application/json"
}{
"containerDefinitions": [
{
"name": "eddi",
"image": "<image-id>.dkr.ecr.<region>.amazonaws.com/eddi:latest",
"cpu": 1024,
"memoryReservation": 2048,
"portMappings": [
{
"containerPort": 7070,
"hostPort": 7070,
"protocol": "tcp"
}
],
"essential": true,
"command": [
"/bin/bash"
],
"environment": [
{
"name": "JAVA_OPTS_APPEND",
"value": "-Dmongodb.connectionString=mongodb+srv://<user>:<password>@<host>/eddi?retryWrites=true&w=majority -Dmongodb.database=eddi"
}
],
"mountPoints": [],
"volumesFrom": [],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "eddi",
"awslogs-region": "<region>",
"awslogs-stream-prefix": "eddi"
}
},
"healthCheck": {
"command": [
"CMD-SHELL",
"curl -f http://localhost:7070/q/health || exit 1"
],
"interval": 30,
"timeout": 5,
"retries": 3
}
}
],
"networkMode": "awsvpc",
"revision": 1,
"volumes": [],
"status": "ACTIVE",
"requiresAttributes": [
{
"name": "com.amazonaws.ecs.capability.logging-driver.awslogs"
},
{
"name": "com.amazonaws.ecs.capability.docker-remote-api.1.24"
},
{
"name": "ecs.capability.execution-role-awslogs"
},
{
"name": "com.amazonaws.ecs.capability.ecr-auth"
},
{
"name": "com.amazonaws.ecs.capability.docker-remote-api.1.19"
},
{
"name": "com.amazonaws.ecs.capability.docker-remote-api.1.21"
},
{
"name": "com.amazonaws.ecs.capability.task-iam-role"
},
{
"name": "ecs.capability.container-health-check"
},
{
"name": "ecs.capability.execution-role-ecr-pull"
},
{
"name": "com.amazonaws.ecs.capability.docker-remote-api.1.18"
},
{
"name": "ecs.capability.task-eni"
}
],
"placementConstraints": [],
"compatibilities": [
"EC2",
"FARGATE"
],
"requiresCompatibilities": [
"EC2",
"FARGATE"
],
"cpu": "1024",
"memory": "2048"
}You have guessed it correctly, another POST to /outputstore/outputsets creates the bot's Output with a JSON in the body like this:
You should again get a return code of 201 with a URI in the location header referencing the newly created output :
eddi://ai.labs.output/outputstore/outputsets/<UNIQUE_OUTPUTSET_ID>?version=<OUTPUTSET_VERSION>
Example :
eddi://ai.labs.output/outputstore/outputsets/5a26d97417312628b46119fc?version=1
Now we will align the just created LifecycleTasks in the Package. Make a POST to /packagestore/packages with a JSON in the body like this:
Name
Description
Required
packageextensions
Array of PackageExtension
PackageExtension.type
possible values, see table below "Extension Types"
PackageExtension.extensions
Array of Object
False
PackageExtension.config
Extension Types in this examples
Extension
Config
eddi://ai.labs.output
Object Config contains param uri with Link to output set, e.g. eddi://ai.labs.output/outputstore/outputsets/5a26d97417312628b46119fc?version=1
eddi://ai.labs.package/packagestore/packages/<UNIQUE_PACKAGE_ID>?version=<PACKAGE_VERSION>
Example
eddi://ai.labs.package/packagestore/packages/5a2ae60f17312624f8b8a445?version=1
See also the API documentation at http://localhost:7070/view#!/configurations/createPackage
Make a POST to /botstore/bots with a JSON like this:
Name
Description
packages
Array of String, references to Packages
b. You should again get a return code of 201 with a URI in the location header referencing the newly created bot :
eddi://ai.labs.bot/botstore/bots/<UNIQUE_BOT_ID>?version=<BOT_VERSION>
Example:
eddi://ai.labs.bot/botstore/bots/5a2ae68a17312624f8b8a446?version=1
See also the API documentation at http://localhost:7070/view#!/configurations/createBot
Finally, we are ready to let the bot fly. From here on, you have the possibility to let an UI do it for you or you do it step by step.
The UI that automates these steps can be reached here: /chat/unrestricted/<UNIQUE_BOT_ID>
Otherwise via REST:
Deploy the Bot:
Make a POST to /administration/unrestricted/deploy/<UNIQUE_BOT_ID>?version=<BOT_VERSION>
You will receive a 202 http code.
Since deployment could take a while it has been made asynchronous.
Make a GET to /administration/unrestricted/deploymentstatus/<UNIQUE_BOT_ID>?version=<BOT_VERSION> to find out the status of deployment.
NOT_FOUND, IN_PROGRESS, ERROR and READY is what you can expect to be returned in the body.
As soon as the Bot is deployed and has READY status, make a POST to /bots/unrestricted/<UNIQUE_BOT_ID>
You will receive a 201 with the URI for the newly created Conversation, like this:
e.g.
eddi://ai.labs.conversation/conversationstore/conversations/<UNIQUE_CONVERSATION_ID>
Now it's time to start talking to our Bot 1. Make a POST to /bots/unrestricted/<UNIQUE_BOT_ID>/<UNIQUE_CONVERSATION_ID>
Option 1: is to hand over the input text as contentType text/plain. Include the User Input in the body as text/plain (e.g. Hello)
Option 2: is to hand over the input as contentType application/json, which also allows you to handover context information that you can use with the eddi configurations 1. Include the User Input in the body as application/json (e.g. Hello)
You have two query params you can use to config the returned output 1. returnDetailed - default is false - will return all sub results of the entire conversation steps, otherwise only public ones such as input, action, output & quickreplies 2. returnCurrentStepOnly - default is true - will return only the latest conversation step that has just been processed, otherwise returns all conversation steps since the beginning of this conversation
The output from the bot will be returned as JSON
If you are interested in fetching the conversationmemory at any given time, make a GET to /bots/unrestricted/<UNIQUE_BOT_ID>/<UNIQUE_CONVERSATION_ID>?returnDetailed=true (the query param is optional, default is false)
If you made it till here, CONGRATULATIONS, you have created your first Chatbot with EDDI !
By the way you can use the attached postman collection below to do all of the steps mentioned above by clicking send on each request in postman.
Create outputSet
Creating package
Creating bot
Deploy the bot
Create conversation
Say Hello to the bot
This feature will allow you to take advantage of EDDI's automatic management of bots, it is possible to avoid creating conversations and managing them yourself, but let them be managed by EDDI.
This will act as a shortcut to start directly a conversation with a bot that covers a specific intent.
But first you will have to set up a BotTrigger.
{
"outputSet": [
{
"action": "CONVERSATION_START",
"timesOccurred": 0,
"outputs": [
{
"valueAlternatives": [
{
"type": "text",
"text": "Hello World!"
}
]
}
]
}
]
}{
"packageExtensions": [
{
"type": "eddi://ai.labs.output",
"config": {
"uri": "eddi://ai.labs.output/outputstore/outputsets/<UNIQUE_OUTPUTSET_ID>?version=<OUTPUTSET_VERSION>"
}
}
]
}{
"packages": [
"eddi://ai.labs.package/packagestore/packages/<UNIQUE_PACKAGE_ID>?version=<PACKAGE_VERSION>"
]
}{
"input": "some user input"
}Config object, but can be empty.
True
Element
Description
intent
(String) keyword or phrase (camel case or with '-') that will be used in managed bots to trigger the bots defined in this model
botDeployments
(Array:<BotDeployment>) array of BotDeployment. If multiple botDeployments are defined, one will be picked randomly.
environment
(String) the environment that you would like (restricted, unrestricted, test)
botId
(String) the id of the bot that you want to create the botTrigger for it.
initialContext
(Array <Object> ) As context can be handed over on each request to the bot, initialContext allows the definition of context the bot should get at the very first conversation step when a conversation with the bot is started (only way to get context to the bot in the first conversation step)
HTTP Method
API Endpoint
Request Body
Response
DELETE
/bottriggerstore/bottriggers/{intent}
N/A
N/A
GET
/bottriggerstore/bottriggers/{intent}
N/A
Bot Triggers-model
PUT
To trigger a managed bot you will have to call the following API endpoints.
HTTP Method
API Endpoint
Request Body
Response
GET
/managedbots/{intent}/{userId}
N/A
Conversation model
POST
/managedbots/{intent}/{userId}
Input model
N/A
POST
Element
Description
{intent}
(String) the label/keyword used originally to point to this BotTrigger
{userId}
(String) used to specify the user who triggered the conversation
Request URL:
POST http://localhost:7070//bottriggerstore/bottriggers
Request Body
Response Body
no content
Response Code
200
Response Headers
Request URL:
POST http://localhost:7070/managedbots/weather_trigger/myUserId
Request Body
Response Body
Response Code
200
Response Headers
In this article we will talk about EDDI's extensions.
EDDI's extensions are the features that your current instance of EDDI is supporting, the latter are used in the process of configuring/developing a Chatbot.
The list of extensions will allow you to have an overview of what is enabled in your current instance of EDDI, the list can be retrieved by calling the API endpoint below.
Note All EDDI's resources start with
eddi://, this is used to distinguish if the resource is an EDDI extension, e.g :callbacks,httpcalls,outputsets,bot packages, etc..
More about regular dictionaries can be found .
Request URL
GET http://localhost:7070/extensionstore/extensions
Response Body
Response Code
200
Response Headers

{
"intent": "string",
"botDeployments": [
{
"environment": "environment",
"botId": "string",
"initialContext": {
"additionalProp1": {
"type": "string",
"value": ""
},
"additionalProp2": {
"type": "string",
"value": ""
},
"additionalProp3": {
"type": "string",
"value": ""
}
}
}
]
}{
"intent": "weather_trigger",
"botDeployments": [
{
"environment": "unrestricted",
"botId": "5bf5418c46e0fb000b7636d0",
"initialContext": {}
}
]
}access-control-allow-headers: authorization, Content-Type
access-control-allow-methods: GET, PUT, POST, DELETE, PATCH, OPTIONS
access-control-allow-origin: *
access-control-expose-headers: location
connection: Keep-Alive
content-length: 0
date: Mon, 18 Mar 2019 00:31:07 GMT
keep-alive: timeout=5, max=100
server: Apache/2.4.29 (Ubuntu){
"input": "Hello managed bot!",
"context": {}
}{
"botId": "5bf5418c46e0fb000b7636d0",
"botVersion": 10,
"userId": "myUserId",
"environment": "unrestricted",
"conversationState": "READY",
"redoCacheSize": 0,
"conversationOutputs": [
{
"input": "Hello managed bot!",
"expressions": "unknown(Hello), unknown(managed), unknown(bot!)",
"intents": [
"unknown",
"unknown",
"unknown"
]
}
],
"conversationProperties": {},
"conversationSteps": [
{
"conversationStep": [
{
"key": "input:initial",
"value": "Hello managed bot!"
}
],
"timestamp": 1552869578596
}
]
}access-control-allow-headers: authorization, Content-Type
access-control-allow-methods: GET, PUT, POST, DELETE, PATCH, OPTIONS
access-control-allow-origin: *
access-control-expose-headers: location
connection: Keep-Alive
content-length: 0
date: Mon, 18 Mar 2019 00:31:07 GMT
keep-alive: timeout=5, max=100
server: Apache/2.4.29 (Ubuntu)/bottriggerstore/bottriggers/{intent}
Bot Triggers-model
N/A
POST
/bottriggerstore/bottriggers
Bot Triggers-model
N/A
/managedbots/{intent}/{userId}/endConversation
Input model
N/A


Element
Value
HTTP Method
GET
API Endpoint
/extensionstore/extensions
Element
Value
type
(String) The type of the extension
displayName
(String) A given name to the extension
configs
(Object) Configuration of the extension
extensions
(Object) Extensions of the extension
[
{
"type": "string",
"displayName": "string",
"configs": {},
"extensions": {}
}
][ {
"type" : "ai.labs.parser",
"displayName" : "Input Parser",
"configs" : {
"includeUnknown" : {
"displayName" : "Include Unknown Expressions",
"fieldType" : "BOOLEAN",
"defaultValue" : true,
"optional" : true
},
"includeUnused" : {
"displayName" : "Include Unused Expressions",
"fieldType" : "BOOLEAN",
"defaultValue" : true,
"optional" : true
},
"appendExpressions" : {
"displayName" : "Append Expressions",
"fieldType" : "BOOLEAN",
"defaultValue" : true,
"optional" : true
}
},
"extensions" : {
"corrections" : [ {
"type" : "ai.labs.parser.corrections.levenshtein",
"displayName" : "Damerau Levenshtein Correction",
"configs" : {
"distance" : {
"displayName" : "Distance",
"fieldType" : "INT",
"defaultValue" : 2,
"optional" : true
}
},
"extensions" : { }
}, {
"type" : "ai.labs.parser.corrections.stemming",
"displayName" : "Grammar Stemming Correction",
"configs" : { },
"extensions" : { }
}, {
"type" : "ai.labs.parser.corrections.phonetic",
"displayName" : "Phonetic Matching Correction",
"configs" : { },
"extensions" : { }
}, {
"type" : "ai.labs.parser.corrections.mergedTerms",
"displayName" : "Merged Terms Correction",
"configs" : { },
"extensions" : { }
} ],
"normalizer" : [ {
"type" : "ai.labs.parser.normalizers.punctuation",
"displayName" : "Punctuation Normalizer",
"configs" : {
"removePunctuation" : {
"displayName" : "Remove Punctuation",
"fieldType" : "BOOLEAN",
"defaultValue" : false,
"optional" : true
},
"punctuationRegexPattern" : {
"displayName" : "Punctuation RegEx Pattern",
"fieldType" : "STRING",
"defaultValue" : "!?:.,;",
"optional" : true
}
},
"extensions" : { }
}, {
"type" : "ai.labs.parser.normalizers.specialCharacter",
"displayName" : "Convert Special Character Normalizer",
"configs" : { },
"extensions" : { }
}, {
"type" : "ai.labs.parser.normalizers.contractedWords",
"displayName" : "Contracted Word Normalizer",
"configs" : { },
"extensions" : { }
}, {
"type" : "ai.labs.parser.normalizers.allowedCharacter",
"displayName" : "Remove Undefined Character Normalizer",
"configs" : { },
"extensions" : { }
} ],
"dictionaries" : [ {
"type" : "ai.labs.parser.dictionaries.integer",
"displayName" : "Integer Dictionary",
"configs" : { },
"extensions" : { }
}, {
"type" : "ai.labs.parser.dictionaries.decimal",
"displayName" : "Decimal Dictionary",
"configs" : { },
"extensions" : { }
}, {
"type" : "ai.labs.parser.dictionaries.ordinalNumber",
"displayName" : "Ordinal Numbers Dictionary",
"configs" : { },
"extensions" : { }
}, {
"type" : "ai.labs.parser.dictionaries.punctuation",
"displayName" : "Punctuation Dictionary",
"configs" : { },
"extensions" : { }
}, {
"type" : "ai.labs.parser.dictionaries.time",
"displayName" : "Time Expression Dictionary",
"configs" : { },
"extensions" : { }
}, {
"type" : "ai.labs.parser.dictionaries.email",
"displayName" : "Email Dictionary",
"configs" : { },
"extensions" : { }
}, {
"type" : "ai.labs.parser.dictionaries.regular",
"displayName" : "Regular Dictionary",
"configs" : {
"uri" : {
"displayName" : "Resource URI",
"fieldType" : "URI",
"optional" : false
}
},
"extensions" : { }
} ]
}
}, {
"type" : "ai.labs.behavior",
"displayName" : "Behavior Rules",
"configs" : {
"appendActions" : {
"displayName" : "Append Actions",
"fieldType" : "BOOLEAN",
"defaultValue" : true,
"optional" : false
},
"uri" : {
"displayName" : "Resource URI",
"fieldType" : "URI",
"optional" : false
}
},
"extensions" : { }
}, {
"type" : "ai.labs.output",
"displayName" : "Output Generation",
"configs" : {
"uri" : {
"displayName" : "Resource URI",
"fieldType" : "URI",
"optional" : false
}
},
"extensions" : { }
}, {
"type" : "ai.labs.templating",
"displayName" : "Templating",
"configs" : { },
"extensions" : { }
}, {
"type" : "ai.labs.property",
"displayName" : "Property Extraction",
"configs" : { },
"extensions" : { }
}, {
"type" : "ai.labs.callback",
"displayName" : "External Callback",
"configs" : {
"callbackUri" : {
"displayName" : "Callback URI",
"fieldType" : "URI",
"optional" : false
},
"callOnActions" : {
"displayName" : "Call on Actions",
"fieldType" : "STRING",
"defaultValue" : "",
"optional" : true
},
"timeoutInMillis" : {
"displayName" : "Timeout in Milliseconds",
"fieldType" : "URI",
"defaultValue" : 10000,
"optional" : true
}
},
"extensions" : { }
}, {
"type" : "ai.labs.httpcalls",
"displayName" : "Http Calls",
"configs" : {
"uri" : {
"displayName" : "Resource URI",
"fieldType" : "URI",
"optional" : false
}
},
"extensions" : { }
} ]{
"access-control-allow-origin": "*",
"date": "Sat, 19 May 2018 22:00:11 GMT",
"content-type": "application/json",
"access-control-allow-headers": "authorization, Content-Type",
"content-length": "6208",
"access-control-allow-methods": "GET, PUT, POST, DELETE, PATCH, OPTIONS",
"access-control-expose-headers": "location"
}






In this section we will talk about how to send/receive messages from a Chatbot, the first step is the creation of the conversation, once you have the conversation Id you will be able to send a message to the Chatbot through a POST and to receive the message through A GET, while having the capacity to send context information through the body of the POST request as well.
Important: EDDI has a great feature for conversations with chatbots, it's the possibility to go back in time by using the two API endpoints :
/undoand/redo!
Note
conversationPropertiescan also be used in output templating e.g:[[${properties.city}]].
The conversationId will be provided through the location HTTP Header of the response, you will use that later to submit messages to the Chabot to maintain a conversation.
Request URL:
http://localhost:7070/bots/unrestricted/5ad2ab182de29719b44a792a
Response Body
no content
Response Code
201
Response Headers
Request URL
http://localhost:7070/bots/restricted/5aaf90e29f7dd421ac3c7dd4/5add1fe8a081a228a0588d1c?returnDetailed=false&returnCurrentStepOnly=true
Request Body
Response Code
200
Response Body
Response Headers
Request URL:
http://localhost:7070/bots/unrestricted/5aaf90e29f7dd421ac3c7dd4/5add1fe8a081a228a0588d1c?returnDetailed=false
Response Body
Response Code
200
Response Headers
The undo and redo methods basically allow you to return a step back in a conversation, this is done by sending a POST along with bot and conversation ids to /bots/{environment}/{botId}/redo/{conversationId} endpoint, the GET call of the same endpoint with the same parameters will allow you to see if the last submitted undo/redo was successful by receiving a true or false in the response body.
Request URL:
http://localhost:7070/bots/restricted/5aaf98e19f7dd421ac3c7de9/undo/5ade58dda081a23418503d6f
Response Body
no content
Response Code
200
Response Headers
(integer) if undo has been performed, this number indicates how many times redo can be done (=times undo has been triggered)
conversationOutputs
(Array: <conversationOutput>) Array of conversationOutput
conversationOutput.input
(String) The user's input.
conversationOutput.expressions
(Array: <String>) an array of the expressions involved in the creation of this reply (output).
conversationOutput.intents
(Array: <String>) an array of the intents involved in the creation of this reply (output).
conversationOutput.actions
(Array: <String>) an array of the actions involved in the creation of this reply (output).
conversationOutput.httpCalls
(Array: <JsonObject>) an array of the httpCalls objects involved in the creation of this reply (output).
conversationOutput.properties
(Array: <JsonObject>) the list of available properties in the current conversation.
conversationOutput.output
(String) The final bot's output
conversationProperties
(Array: <>) Array of conversationProperty, <nameOfProperty> is a dynamic value that represents the name of the property
<nameOfProperty>.name
(String) name of the property.
<nameOfProperty>.value
(String|JsonObject) value of the property.
<nameOfProperty>.scope
(String) scope can be
step (=valid one interaction [user input to user output]),
conversation (=valid for the entire conversation),
longTerm (=valid across conversations [based on given userId])
conversationSteps
(Array: <conversationStep>) Array of conversationStep.
conversationStep.key
(String) the element key in the conversationStep e.g key : input:initial, actions
conversationStep.value
(String) the element value of the conversationStep e.g in case of actionq as key it could be an array string [ "current_weather_in_city" ].
timestamp.timestamp
(dateTime) the timestamp in (ISO 8601) format
(Query parameter):Boolean - Default : false
returnCurrentStepOnly
(Query parameter):Boolean - Default : true
Request Body
JSON Object , example : { "input": "the message", "context": {} }
The context here is where you pass context variables that can be evaluated by EDDI, we will be explaining this in more details in Passing Context Information
(Query parameter):Boolean - Default : false
Element
Tags
HTTP Method
POST
API endpoint
/bots/{environment}/{botId}
{environment}
(Path parameter):String Deployment environment (e.g: restricted,unrestricted,test)
{botId}
(Path parameter):String Id of the bot that you wish to start conversation with.
Element
Tags
botId
(String) The id of the bot that sent the reply.
botVersion
(integer) The version of the bot that sent the reply.
userId
(String) The id of the user who interacted with the bot.
environment
(String) the name of the environment where the bot is deployed
conversationState
(String) The state of the current conversation, could be:
READY,
IN_PROGRESS,
ENDED,
EXECUTION_INTERRUPTED,
ERROR
Element
Tags
HTTP Method
POST
API endpoint
/bots/{environment}/{botId}/{conversationId}
{environment}
(Path parameter):String Deployment environment (e.g: restricted,unrestricted,test)
botId
(Path parameter):String Id of the bot that you wish to continue a conversation with.
conversationId
(Path parameter): String Id of the conversation that you wish to send the message to.
Element
Tags
HTTP Method
GET
API endpoint
/bots/{environment}/{botId}/{conversationId}
{environment}
(Path parameter):String Deployment environment (e.g: restricted,unrestricted,test)
{botId}
(Path parameter):String Id of the bot that you wish to continue a conversation with.
{conversationId}
(Path parameter): String Id of the conversation that you wish to receive a the message from.
Element
Tags
HTTP Method
POST
API endpoint
/bots/{environment}/{botId}/[undo/redo]/{conversationId}
{environment}
(Path parameter):String Deployment environment (e.g: restricted,unrestricted,test)
{botId}
(Path parameter):String Id of the bot that you wish to continue a conversation with.
{conversationId}
(Path parameter): String Id of the conversation that you wish to undo/redo the last conversation step.
redoCount
returnDetailed
returnDetailed
{
"botId": "string",
"botVersion": Integer,
"userId": "string",
"environment": "string",
"conversationState": "string",
"redoCacheSize": 0,
"conversationOutputs": [
"input" : "string",
"expressions" : <arrayOfString>,
"intents" : <arrayOfString>,
"actions" : <arrayOfString>,
"httpCalls" : {JsonObject},
"properties" : <arrayOfString>,
"output" : "string"
],
"conversationProperties": {
"<nameOfProperty>" : {
"name" : "string",
"value" : "string" | {JsonObject},
"scope" : "string"
}},
"conversationSteps": [
{
"conversationStep": [
{
"key": "string",
"value": {}
}
],
"timestamp": "dateTime"
}
]
}{
"botId": "5bf5418c46e0fb000b7636d0",
"botVersion": 10,
"userId": "anonymous-zj1p1GDtM5",
"environment": "unrestricted",
"conversationState": "READY",
"redoCacheSize": 0,
"conversationOutputs": [
{
"input": "madrid",
"expressions": "unknown(madrid)",
"intents": [
"unknown"
],
"actions": [
"current_weather_in_city"
],
"httpCalls": {
"currentWeather": {
"coord": {
"lon": -3.7,
"lat": 40.42
},
"weather": [
{
"id": 800,
"main": "Clear",
"description": "clear sky",
"icon": "01n"
}
],
"base": "stations",
"main": {
"temp": 10.86,
"pressure": 1019,
"humidity": 66,
"temp_min": 8.33,
"temp_max": 13.33
},
"visibility": 10000,
"wind": {
"speed": 5.7,
"deg": 240
},
"clouds": {
"all": 0
},
"dt": 1551735805,
"sys": {
"type": 1,
"id": 6443,
"message": 0.0049,
"country": "ES",
"sunrise": 1551681788,
"sunset": 1551723011
},
"id": 3117735,
"name": "Madrid",
"cod": 200
}
},
"properties": {
"currentWeather": {
"coord": {
"lon": -3.7,
"lat": 40.42
},
"weather": [
{
"id": 800,
"main": "Clear",
"description": "clear sky",
"icon": "01n"
}
],
"base": "stations",
"main": {
"temp": 10.86,
"pressure": 1019,
"humidity": 66,
"temp_min": 8.33,
"temp_max": 13.33
},
"visibility": 10000,
"wind": {
"speed": 5.7,
"deg": 240
},
"clouds": {
"all": 0
},
"dt": 1551735805,
"sys": {
"type": 1,
"id": 6443,
"message": 0.0049,
"country": "ES",
"sunrise": 1551681788,
"sunset": 1551723011
},
"id": 3117735,
"name": "Madrid",
"cod": 200
},
"city": "madrid"
},
"output": [
"The current weather situation of madrid is clear sky at 10.86 °C"
]
}
],
"conversationProperties": {
"city": {
"name": "city",
"value": "madrid",
"scope": "conversation"
}
},
"conversationSteps": [
{
"conversationStep": [
{
"key": "input:initial",
"value": "madrid"
},
{
"key": "actions",
"value": [
"current_weather_in_city"
]
},
{
"key": "output:text:current_weather_in_city",
"value": "The current weather situation of madrid is clear sky at 10.86 °C"
}
],
"timestamp": 1551736024776
}
]
}{
"access-control-allow-origin": "*",
"date": "Sun, 15 Apr 2018 01:45:09 GMT",
"access-control-allow-headers": "authorization, Content-Type",
"content-length": "0",
"location": "eddi://ai.labs.conversation/conversationstore/conversations/5ad2aea52de29719b44a792c",
"access-control-allow-methods": "GET, PUT, POST, DELETE, PATCH, OPTIONS",
"access-control-expose-headers": "location",
"content-type": null
}{
"input": "Hi!",
"context": {}
}{
"botId": "5aaf90e29f7dd421ac3c7dd4",
"botVersion": 1,
"environment": "restricted",
"conversationState": "READY",
"redoCacheSize": 0,
"conversationSteps": [
{
"conversationStep": [
{
"key": "input:initial",
"value": "Hi!"
}
],
"timestamp": 1524441253098
}
]
}{
"access-control-allow-origin": "*",
"date": "Sun, 22 Apr 2018 23:54:12 GMT",
"access-control-allow-headers": "authorization, Content-Type",
"content-length": "321",
"access-control-allow-methods": "GET, PUT, POST, DELETE, PATCH, OPTIONS",
"content-type": "application/json;resteasy-server-has-produces=true"
}{
"botId": "5aaf90e29f7dd421ac3c7dd4",
"botVersion": 1,
"environment": "restricted",
"conversationState": "READY",
"redoCacheSize": 0,
"conversationSteps": [
{
"conversationStep": [
{
"key": "actions",
"value": [
"global_menu"
]
},
{
"key": "output:text:global_menu",
"value": "What do you want to do?"
},
{
"key": "quickReplies:global_menu",
"value": [
{
"value": "Show me your skillz",
"expressions": "confirmation(show_skills)",
"default": false
},
{
"value": "Tell me a joke",
"expressions": "trigger(tell_a_joke)",
"default": false
}
]
}
],
"timestamp": 1524441064450
},
{
"conversationStep": [
{
"key": "input:initial",
"value": "Hi!"
}
],
"timestamp": 1524441253098
}
]
}{
"access-control-allow-origin": "*",
"date": "Mon, 23 Apr 2018 00:07:25 GMT",
"cache-control": "no-cache",
"access-control-allow-headers": "authorization, Content-Type",
"content-length": "891",
"access-control-allow-methods": "GET, PUT, POST, DELETE, PATCH, OPTIONS",
"content-type": "application/json"
}{
"access-control-allow-origin": "*",
"date": "Mon, 23 Apr 2018 22:20:57 GMT",
"access-control-allow-headers": "authorization, Content-Type",
"content-length": "0",
"access-control-allow-methods": "GET, PUT, POST, DELETE, PATCH, OPTIONS",
"content-type": null
}Behavior RulesGroupEach 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 conversation
never - 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:
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
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)
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.
Defines the occurrence/frequency of an action in a Behavior Rule.
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.
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.
This will allow you to compile a condition based on any http request/properties or any sort of variables available in EDDI's context.
The API Endpoints below will allow you to manage the Behavior Rules 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
We will demonstrate here the creation of a BehaviorSet
Request URL
POST http://localhost:7070/behaviorstore/behaviorsets
Request Body
Response Body
no content
Response Code
201
Response Headers
{
"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>
]
}
]
}(...)
"conditions": [
{
"type": "inputmatcher",
"configs": {
"expressions": "greeting(*)",
"occurrence": "currentStep"
}
}
]
(...)(...)
"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"
}
}
]
(...)(...)
"conditions": [
{
"type": "connector",
"configs": {
"operator": "OR"
},
"conditions": [
<any other conditions>
]
}
]
(...)Child 1 - true
Child 2 - true
→ Negation = false
Child 1 - false
Child 2 - true
→ Negation = true
(...)
"conditions": [
{
"type": "negation",
"conditions": [
<any other conditions>
]
}
]
(...)(...)
{
"type": "occurrence",
"configs": {
"maxTimesOccurred": "0",
"minTimesOccurred": "0",
"behaviorRuleName": "Welcome"
}
}
(...)(...)
{
"type": "dependency",
"configs": {
"reference": "<name-of-another-behavior-rule>"
}
}
(...)(...)
{
"type": "actionmatcher",
"configs": {
"actions": "show_available_products",
"occurrence": "lastStep"
}
}
(...)(...)
{
"type": "dynamicvaluematcher",
"configs": {
"valuePath": "memory.current.httpCalls.someObj.errors",
"contains": "partly matching",
"equals": "needs to be equals"
}
}
(...){
"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"
}
}
]
}
]
}
]
}{
"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
}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)
/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
Prerequisites: Up and Running instance of EDDI (see: Getting started)
Follow these steps to create the configuration files you will need:
See also
Create regular dictionaries in order to store custom words and phrases. A dictionary is there to map user input to expressions, which are later used in Behavior Rules. A POST to /regulardictionarystore/regulardictionaries with a JSON in the body like this:
Example using CURL:
The returned URI is a reference for this specific resource. This resource will be referenced in the bot definition.
See also Behavior Rules
Next, create a behaviorRule resource to configure the decision making a. Make a POST to /behaviorstore/behaviorsets with a JSON in the body like this:
You should again get a return code of 201 with a URI in the location header referencing the newly created Behavior Rules:
eddi://ai.labs.behavior/behaviorstore/behaviorsets/<UNIQUE_BEHAVIOR_ID>?version=<BEHAVIOR_VERSION>
Example:
eddi://ai.labs.behavior/behaviorstore/behaviorsets/5a26d8fd17312628b46119fb?version=1
You have guessed it correctly, another POST to /outputstore/outputsets creates the bot's Output with a JSON in the body like this:
You should again get a return code of 201 with a URI in the location header referencing the newly created output :
eddi://ai.labs.output/outputstore/outputsets/<UNIQUE_OUTPUTSET_ID>?version=<OUTPUTSET_VERSION>
Example :
eddi://ai.labs.output/outputstore/outputsets/5a26d97417312628b46119fc?version=1
Now we will align the just created LifecycleTasks in the Package. Make a POST to /packagestore/packages with a JSON in the body like this:
Extension Types
New
Now you can use the new feature of defining properties in the package definition : This can be used by introducing an extension with type eddi://ai.labs.property which has the config model as follows:
You should again get a return code of 201 with an URI in the location header referencing the newly created package format
eddi://ai.labs.package/packagestore/packages/<UNIQUE_PACKAGE_ID>?version=<PACKAGE_VERSION>
Example
eddi://ai.labs.package/packagestore/packages/5a2ae60f17312624f8b8a445?version=1
See also the API documentation at
Make a POST to /botstore/bots with a JSON like this:
b. You should again get a return code of 201 with a URI in the location header referencing the newly created bot :
eddi://ai.labs.bot/botstore/bots/<UNIQUE_BOT_ID>?version=<BOT_VERSION>
Example:
eddi://ai.labs.bot/botstore/bots/5a2ae68a17312624f8b8a446?version=1
See also the API documentation at
Finally, we are ready to let the bot fly. From here on, you have the possibility to let an UI do it for you or you do it step by step.
The UI that automates these steps can be reached here: /chat/unrestricted/<UNIQUE_BOT_ID>
Otherwise via REST:
Deploy the Bot:
Make a POST to /administration/unrestricted/deploy/<UNIQUE_BOT_ID>?version=<BOT_VERSION>
You will receive a 202 http code.
NOT_FOUND, IN_PROGRESS, ERROR and READY is what you can expect to be returned in the body.
As soon as the Bot is deployed and has READY status, make a POST to /bots/unrestricted/<UNIQUE_BOT_ID>
You will receive a 201 with the URI for the newly created Conversation, like this:
Option 1: is to hand over the input text as contentType text/plain. Include the User Input in the body as text/plain (e.g. Hello)
Option 2: is to hand over the input as contentType application/json, which also allows you to handover context information that you can use with the eddi configurations 1. Include the User Input in the body as application/json (e.g. Hello)
You have two query params you can use to config the returned output 1. returnDetailed - default is false - will return all sub results of the entire conversation steps, otherwise only public ones such as input, action, output & quickreplies 2. returnCurrentStepOnly - default is true - will return only the latest conversation step that has just been processed, otherwise returns all conversation steps since the beginning of this conversation
The output from the bot will be returned as JSON
If you are interested in fetching the
If you made it till here, CONGRATULATIONS, you have created your first Chatbot with EDDI !
By the way you can use the attached postman collection below to do all of the steps mentioned above by clicking send on each request in postman.
Create dictionary (greetings)
Create behaviourSet
Create outputSet
Creating package
Word.frequency
int, Used for a randomizer
Phrase.phrase
String, Spaces allowed
True
Phrase.expressions
String, "greeting(hello)": "greeting" is the category of this expression and "hello" is an entity.
String, allowed values:
—>"inputmatcher" (has params: "expressions" (Array of String( and "occurrence")
—>"negation" (BehaviorExtension object, has params: "conditions" and "occurrence")
RuleChild.values
HashMap, allowed values:
—>"expressions": String, mandatory. Expression e.g. "greeting(*)" or "how_are_you"
—>"occurrence": String, optional. Allowed values "currentStep"
Negation.conditons
Array of NegationChild
NegationChild.type
String e.g. "occurrence"
NegationChild.values
HashMap, allowed values:
—>"maxTimesOccurred": String, e.g. 1
—>"minTimesOccurred": String, e.g. 1
—>"behaviorRuleName": String
True
Make a GET to /administration/unrestricted/deploymentstatus/<UNIQUE_BOT_ID>?version=<BOT_VERSION> to find out the status of deployment.
e.g.
eddi://ai.labs.conversation/conversationstore/conversations/<UNIQUE_CONVERSATION_ID>
Now it's time to start talking to our Bot 1. Make a POST to /bots/unrestricted/<UNIQUE_BOT_ID>/<UNIQUE_CONVERSATION_ID>
GET/bots/unrestricted/<UNIQUE_BOT_ID>/<UNIQUE_CONVERSATION_ID>?returnDetailed=trueCreating bot
Deploy the bot
Create conversation
Say Hello to the bot
Name
Description
Required
words
Array of Word
phrases
Array of Phrase
Word.word
String, single word, no spaces.
True
Word.expressions
Name
Description
BehaviorRule.name
String, e.g. "Smalltalk"
BehaviourGroup.behaviorRules
Array of BehaviorRule
BehaviorRule.name
String, e.g. "Greeting"
BehaviorRule.actions
Array of String, e.g. "greet" or "CONVERSATION_END"
BehaviorRule.conditions
Array of RuleChild
Name
Description
Required
packageextensions
Array of PackageExtension
PackageExtension.type
possible values, see table below "Extension Types"
PackageExtension.extensions
Array of Object
False
PackageExtension.config
Extension
Config
eddi://ai.labs.parser
Dictionaries and/or corrections
Object "extensions" can contain "dictionaries" (Array of Dictionary) and/or "corrections" (Array of Correction)
Object "Dictionary" has params "type" and "config" (optional)
Dictionary.type can reference Regular-Dictionaries "eddi://ai.labs.parser.dictionaries.regular" (needs param "config.uri") or be one of the EDDI out of the box types:
—>"eddi://ai.labs.parser.dictionaries.integer"
—>"eddi://ai.labs.parser.dictionaries.decimal"
—>"eddi://ai.labs.parser.dictionaries.punctuation"
—>"eddi://ai.labs.parser.dictionaries.email"
—>"eddi://ai.labs.parser.dictionaries.time"
—>"eddi://ai.labs.parser.dictionaries.ordinalNumber"
Object "Correction" has params "type" and "config" (optional)
Correction.type can reference one of the EDDI out of the box types:
—>"eddi://ai.labs.parser.corrections.stemming": Object "config" has params "language" (String e.g. "english") and "lookupIfKnown" (Boolean)
—>"eddi://ai.labs.parser.corrections.levenshtein": Object "config" has param "distance" (Integer, e.g. 2)
—>"eddi://ai.labs.parser.corrections.mergedTerms"
eddi://ai.labs.behavior
Object Config contains param uri with Link to a behavior set, e.g. eddi://ai.labs.behavior/behaviorstore/behaviorsets/5a26d8fd17312628b46119fb?version=1
eddi://ai.labs.output
Object Config contains param uri with Link to output set, e.g. eddi://ai.labs.output/outputstore/outputsets/5a26d97417312628b46119fc?version=1
Name
Description
setOnActions.actions
(string) defines which for which actions (triggered by BehaviorRules) these Properties should be set
setOnActions.setProperties
(Array <Property>: ) must respect the Propertymodel: name, fromObjectPath and scope.
setOnActions.setProperties.name
(string) name of the Property.
setOnActions.setProperties.fromObjectPath
(string) path to the json object.
setOnActions.setProperties.scope
(string) Possible values step, conversation and longTerm .
Name
Description
packages
Array of String, references to Packages
channels
Array of Channel,
Channel.type
String, e.g. "eddi://ai.labs.channel.facebook"
Channel.config
Config Object. For "Facebook" this object has the params "appSecret" (String), "verificationToken" (String), "pageAccessToken" (String)
String, "greeting(hello)": "greeting" is the category of this expression and "hello" is an entity.
RuleChild.type
Config object, but can be empty.
{
"words": [
{
"word": "hello",
"expressions": "greeting(hello)",
"frequency": 0
},
{
"word": "hi",
"expressions": "greeting(hi)",
"frequency": 0
},
{
"word": "bye",
"expressions": "goodbye(bye)",
"frequency": 0
},
{
"word": "thanks",
"expressions": "thanks(thanks)",
"frequency": 0
}
],
"phrases": [
{
"phrase": "good afternoon",
"expressions": "greeting(good_afternoon)"
},
{
"phrase": "how are you",
"expressions": "how_are_you"
}
]
}curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' -d '{ \
"language" : "en", \
"words" : [ \
{ \
"word" : "hello", \
"expressions" : "greeting(hello)", \
"frequency" : 0 \
}, \
{ \
"word" : "hi", \
"expressions" : "greeting(hi)", \
"frequency" : 0 \
}, \
{ \
"word" : "bye", \
"expressions" : "goodbye(bye)", \
"frequency" : 0 \
}, \
{ \
"word" : "thanks", \
"expressions" : "thanks(thanks)", \
"frequency" : 0 \
} \
], \
"phrases" : [ \
{ \
"phrase" : "good afternoon", \
"expressions" : "greeting(good_afternoon)" \
}, \
{ \
"phrase" : "how are you", \
"expressions" : "how_are_you" \
} \
] \
}' 'http://localhost:7070/regulardictionarystore/regulardictionaries'{
"behaviorGroups": [
{
"name": "Smalltalk",
"behaviorRules": [
{
"name": "Welcome",
"actions": [
"welcome"
],
"conditions": [
{
"type": "occurrence",
"configs": {
"maxTimesOccurred": "0",
"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"
}
}
]
}
]
}
]
}{
"outputSet": [
{
"action": "welcome",
"timesOccurred": 0,
"outputs": [
{
"valueAlternatives": [
{
"type": "text",
"text": "Welcome!"
}
]
},
{
"valueAlternatives": [
{
"type": "text",
"text": "My name is E.D.D.I"
}
]
}
],
"quickReplies": [
{
"value": "Hi EDDI",
"expressions": "greeting(hi)"
},
{
"value": "Bye EDDI",
"expressions": "goodbye(bye)"
}
]
},
{
"action": "greet",
"timesOccurred": 0,
"outputs": [
{
"valueAlternatives": [
{
"type": "text",
"text": "Hi there! Nice to meet up! :-)"
},
{
"type": "text",
"text": "Hey you!"
}
]
}
]
},
{
"action": "greet",
"timesOccurred": 1,
"outputs": [
{
"valueAlternatives": [
{
"type": "text",
"text": "Did we already say hi ?! Well, twice is better than not at all! ;-)"
}
]
}
]
},
{
"action": "say_goodbye",
"timesOccurred": 0,
"outputs": [
{
"valueAlternatives": [
{
"type": "text",
"text": "See you soon!"
}
]
}
]
},
{
"action": "thank",
"timesOccurred": 0,
"outputs": [
{
"valueAlternatives": [
{
"type": "text",
"text": "Your Welcome!"
}
]
}
]
},
{
"action": "how_are_you",
"timesOccurred": 0,
"outputs": [
{
"valueAlternatives": [
{
"type": "text",
"text": "Pretty good.. having lovely conversations all day long.. :-D"
}
]
}
]
}
]
}{
"packageExtensions": [
{
"type": "eddi://ai.labs.parser",
"extensions": {
"dictionaries": [
{
"type": "eddi://ai.labs.parser.dictionaries.integer"
},
{
"type": "eddi://ai.labs.parser.dictionaries.decimal"
},
{
"type": "eddi://ai.labs.parser.dictionaries.punctuation"
},
{
"type": "eddi://ai.labs.parser.dictionaries.email"
},
{
"type": "eddi://ai.labs.parser.dictionaries.time"
},
{
"type": "eddi://ai.labs.parser.dictionaries.ordinalNumber"
},
{
"type": "eddi://ai.labs.parser.dictionaries.regular",
"config": {
"uri": "eddi://ai.labs.regulardictionary/regulardictionarystore/regulardictionaries/<UNIQUE_DICTIONARY_ID>?version=<DICTIONARY_VERSION>"
}
}
],
"corrections": [
{
"type": "eddi://ai.labs.parser.corrections.stemming",
"config": {
"language": "english",
"lookupIfKnown": "false"
}
},
{
"type": "eddi://ai.labs.parser.corrections.levenshtein",
"config": {
"distance": "2"
}
},
{
"type": "eddi://ai.labs.parser.corrections.mergedTerms"
}
]
},
"config": {}
},
{
"type": "eddi://ai.labs.behavior",
"config": {
"uri": "eddi://ai.labs.behavior/behaviorstore/behaviorsets/<UNIQUE_BEHAVIOR_ID>?version=<BEHAVIOR_VERSION>"
}
},
{
"type": "eddi://ai.labs.output",
"config": {
"uri": "eddi://ai.labs.output/outputstore/outputsets/<UNIQUE_OUTPUTSET_ID>?version=<OUTPUTSET_VERSION>"
}
}
]
}{
"type": "eddi://ai.labs.property",
"config": {
"setOnActions": [
{
"actions": "string",
"setProperties": [
{
"name": "string",
"fromObjectPath": "string",
"scope": "string"
}
]
}
]
}
}{
"packageExtensions": [
...
{
"type": "eddi://ai.labs.property",
"config": {
"setOnActions": [
{
"actions": "currentWeather",
"setProperties": [
{
"name": "city",
"fromObjectPath": "memory.current.input",
"scope": "longTerm"
}
]
}
]
}
},
...
{
"type": "eddi://ai.labs.property",
"config": {
"setOnActions": [
{
"actions": "currentWeather",
"setProperties": [
{
"name": "currentWeather",
"fromObjectPath": "memory.current.httpCalls.currentWeather",
"scope": "conversation"
}
]
}
]
}
},
...
]
}{
"packages": [
"eddi://ai.labs.package/packagestore/packages/<UNIQUE_PACKAGE_ID>?version=<PACKAGE_VERSION>"
],
"channels": []
}{
"input": "some user input"
}In this article we will talk about EDDI's httpCalls feature (calling other JSON APIs).
The httpCalls feature allows a Chatbot to consume 3rd party APIs and use the JSON response in another httpCall (for authentication or requesting a token for instance) or directly print the results in Chatbot's Output, this means, for example, you can call a weather API and use the JSON response in your Chatbot's output if the user asks about today's weather or the week's forecast!
We will emphasize the httpCall model and go through an example step by step, you can also download the example in Postman collection format and run the steps.
An httpCall is mainly composed from the targetServer array of httpCalls, the latter will have request where you put all details about your actual http request (method,path,headers, etc..) and postResponse where you can define what happens after the httpCall has been executed and a response has been received; such as quick replies by using qrBuildInstruction.
You can use ${memory.current.httpCalls.<responseObjectName>} to access your JSON object, so you can use it in output templating or in another httpCall, for example an httpCall will get the oAuth token and another httpCall will use in the http headers to authenticate to an API.
We will do a step by step example from scratch (Chatbot creation to a simple conversation that uses httpCall)
For the sake of simplicity we will use a free weather API to fetch weather of cities by their names ().
More about regular dictionaries can be found .
Request URL
POST http://localhost:7070/regulardictionarystore/regulardictionaries
Request Body
Response Body
no content
Response Code
201
Response Headers
More about behaviorSets can be found in
Request URL
POST http://localhost:7070/behaviorstore/behaviorsets
Response Body
no content
Response Code
201
Request Body
Response Headers
Note that we can pass user input to the http call using [[${memory.current.input}]]
Request URL
POST http://localhost:7070/httpcallsstore/httpcalls
Request Body
Response Body
no content
Response Code
201
Response Headers
More about outputSet can be found .
Note When you set
"saveResponse" : trueinhttpCallthen you can use[[${memory.current.httpCalls.<responseObjectName>}]]to access the response data and usethymeleaf(th:each) to iterate overJSONarraysif you have them in yourJSONresponse.
Request URL
POST http://localhost:7070/outputstore/outputsets
Request Body
Response Body
no content
Response Code
201
Response Headers
More about packages can be found .
Important Package note
ai.labs.httpcalls&ai.labs.outputmust come afterai.labs.behaviorin order of the package definition
ai.labs.templating
Request URL
POST http://localhost:7070/packagestore/packages
Request Body
Response Body
no content
Response Code
201
Response Headers
Request URL
POST http://localhost:7070/botstore/bots
Request Body
Response Body
no content
Response Code
201
Response Headers
Request URL
POST http://localhost:7070/administration/restricted/deploy/**<bot_id>**?version=1&autoDeploy=true
Response Body
no content
Response Code
202
Response Headers
Request URL
POST http://localhost:7070/bots/**<env>**/**<bot_id>**
Response Body
no content
Response Code
201
Response Headers
Request URL
POST http://localhost:7070/bots/<env>/<bot_id>/<conversation_id>?returnDetailed=false&returnCurrentStepOnly=true
Request Body
Response Body
Response Code
200
Response Headers
Request URL
POST http://localhost:7070/bots/<env>/<bot_id>/<conversation_id>?returnDetailed=false&returnCurrentStepOnly=true
Request Body
Response Code
200
Response Headers
If you would like to run the full example through postman, you can download and import the collection below.
(String) JSON path to the target array to be used as body of requests e.g: "memory.current.output"
httpCall.preRequest.batchRequests.iterationObjectName
(String) name of the variable to be used for each element of array found in pathToTargetArray
httpCall.request.path
(String) path in the targetServer of the httpCall (e.g /books)
httpCall.request.headers
(Array:<key, value> ) for each httpCall HTTP header
httpCall.request.queryParams
(Array: <key, value>) for each httpCall query parameter
httpCall.request.method
(String) HTTP Method of the httpCall (e.g GET,POST,etc...)
httpCall.request.contentType
(String) value of the contentType HTTP header of the httpCall
httpCall.request.body
(String) an escaped JSON object that goes in the HTTP Request body if needed.
httpCall.postResponse.qrBuildInstruction.pathToTargetArray
(String) path to the array in your JSON response data.
httpCall.postResponse.qrBuildInstruction.iterationObjectName
(String) a variable name that will point to the TargetArray.
httpCall.postResponse.qrBuildInstruction.quickReplyValue
(String) thymeleaf expression to use as a quickReply value.
httpCall.postResponse.qrBuildInstruction.quickReplyExpressions
(String) expression to retrieve a property from iterationObjectName.
httpCall.postResponse.propertyInstructions.name
(String) name of property to be used in templating
httpCall.postResponse.propertyInstructions.value
(String) a static value can be set here if fromObjectPath is not defined.
httpCall.postResponse.propertyInstructions.scope
(String) Can be either :
step used for only for one user interaction
conversation for entire conversation and
longTerm for between conversations
httpCall.postResponse.propertyInstructions.fromObjectPath
(String) JSON path to the saved object e.g savedObjName.something.something
httpCall.postResponse.propertyInstructions.override
(Boolean) flag for override
httpCall.postResponse.propertyInstructions.httpCodeValidator.runOnHttpCode
(Array: <Integer> ) a list of http code that enables this property instruction e.g [200]
httpCall.postResponse.propertyInstructions.httpCodeValidator.skipOnHttpCode
(Array: <Integer>) list of http code that enables this property instruction e.g [500,501,400]
N/A
N/A
GET
/httpcallsstore/httpcalls/{id}
N/A
http-call-model
PUT
/httpcallsstore/httpcalls/{id}
http-call-model
N/A
GET
/httpcallsstore/httpcalls/{id}/currentversion
N/A
http-call-model
POST
/httpcallsstore/httpcalls/{id}/currentversion
http-call-model
N/A
ai.labs.outputElement
Description
targetServerUrl
(String) root/context path of the httpCall (e.g http://example.com/api)
httpCall.saveResponse
(Boolean) whether to save the JSON response into ${memory.current.httpCalls}
httpCall.fireAndForget
(Boolean) whether to execute the request without waiting for a response to be returned, (useful for POST)
httpCall.responseObjectName
(String) name of the JSON object so it can be accessed from other httpCalls or outputsets.
httpCall.actions
(String) name of the output/behavior set mapped to this http call.
HTTP Method
API Endpoint
Request Body
Response
POST
/httpcallsstore/httpcalls
http-call-model
N/A
GET
/httpcallsstore/httpcalls/descriptors
N/A
list of references to http-call-model
DELETE
httpCall.preRequest.batchRequests.pathToTargetArray
/httpcallsstore/httpcalls/{id}
{
"targetServerUrl": "string",
"httpCalls": [
{
"name": "string",
"saveResponse": boolean,
"fireAndForget": boolean,
"responseObjectName": "string",
"actions": [
"string"
],
"preRequest": {
"batchRequests": {
"pathToTargetArray": "string",
"iterationObjectName": "string"
}
},
"request": {
"path": "string",
"headers": {},
"queryParams": {},
"method": "string",
"contentType": "string",
"body": "string"
},
"postResponse": {
"qrBuildInstruction": {
"pathToTargetArray": "String",
"iterationObjectName": "String",
"quickReplyValue": "String",
"quickReplyExpressions": "String"
},
"propertyInstructions": [
{
"name": "string",
"value": "string",
"scope": "string",
"fromObjectPath": "savedObjName.something.something",
"override": boolean,
"httpCodeValidator": {
"runOnHttpCode": [
<array of Integers>
],
"skipOnHttpCode": [
<array of Integers>
]
}
}
]
}
}
]
}{
"targetServerUrl": "https://api.bot-metrics.com/v1/messages",
"httpCalls": [
{
"name": "sendUserMessageToAnalytics",
"actions": [
"send_input_to_analytics"
],
"saveResponse": false,
"fireAndForget": true,
"request": {
"method": "post",
"queryParams": {
"token": "<token>"
},
"contentType": "application/json",
"body": "{\"text\": \"[[${memory.current.input}]]\",\"message_type\": \"incoming\",\"user_id\": \"[[${memory.current.userInfo.userId}]]\",\"platform\": \"eddi\"}"
}
},
{
"name": "sendBotMessageToAnalytics",
"actions": [
"send_output_to_analytics"
],
"saveResponse": false,
"fireAndForget": true,
"preRequest": {
"batchRequests": {
"pathToTargetArray": "memory.current.output",
"iterationObjectName": "output"
}
},
"request": {
"method": "post",
"queryParams": {
"token": "<token>"
},
"contentType": "application/json",
"body": "{\"text\": \"[[${output}]]\",\"message_type\": \"outgoing\",\"user_id\": \"[[${memory.current.userInfo.userId}]]\",\"platform\": \"eddi\"}"
},
"postResponse": {
"propertyInstructions": [
{
"name": "nameOfPropertyToBeUsedInTemplating",
"value": "StaticValueHereIfFromObjectPathIsNotDefined",
"scope": "step",
"fromObjectPath": "savedObjName.something.something",
"override": true,
"httpCodeValidator": {
"runOnHttpCode": [
200
],
"skipOnHttpCode": [
0,
400,
401,
402,
403,
404,
409,
410,
500,
501,
502
]
},
"qrBuildInstruction": {
"pathToTargetArray": "savedObjName.data.topics",
"iterationObjectName": "topic",
"templateFilterExpression": "${topic.subType} != 'specialSubType'",
"quickReplyValue": "[(${topic.name})]",
"quickReplyExpressions": "property(topic_id([(${topic.id})]))"
}
}
]
}
}
]
}{
"words": [
{
"word": "weather",
"expressions": "trigger(current_weather)",
"frequency": 0
}
],
"phrases": [
{
"phrase": "what is the weather",
"expressions": "trigger(current_weather)"
},
{
"phrase": "whats the weather",
"expressions": "trigger(current_weather)"
}
]
}{
"access-control-allow-origin": "*",
"date": "Sun, 13 May 2018 16:40:58 GMT",
"access-control-allow-headers": "authorization, Content-Type",
"content-length": "0",
"location": "eddi://ai.labs.regulardictionary/regulardictionarystore/regulardictionaries/5af86a9aba31c023bcb9ef2b?version=1",
"access-control-allow-methods": "GET, PUT, POST, DELETE, PATCH, OPTIONS",
"access-control-expose-headers": "location",
"content-type": null
}{
"behaviorGroups": [
{
"name": "",
"behaviorRules": [
{
"name": "Ask for City",
"actions": [
"ask_for_city"
],
"conditions": [
{
"type": "inputmatcher",
"configs": {
"expressions": "trigger(current_weather)"
}
}
]
},
{
"name": "Current Weather in City",
"actions": [
"current_weather_in_city"
],
"conditions": [
{
"type": "inputmatcher",
"configs": {
"expressions": "trigger(current_weather)",
"occurrence": "lastStep"
}
}
]
}
]
}
]
}{
"access-control-allow-origin": "*",
"date": "Sun, 13 May 2018 16:45:52 GMT",
"access-control-allow-headers": "authorization, Content-Type",
"content-length": "0",
"location": "eddi://ai.labs.behavior/behaviorstore/behaviorsets/5af86bc0ba31c023bcb9ef2c?version=1",
"access-control-allow-methods": "GET, PUT, POST, DELETE, PATCH, OPTIONS",
"access-control-expose-headers": "location",
"content-type": null
}{
"targetServerUrl": "https://api.openweathermap.org/data/2.5/weather",
"httpCalls": [
{
"name": "currentWeather",
"saveResponse": true,
"responseObjectName": "currentWeather",
"actions": [
"current_weather_in_city"
],
"request": {
"path": "",
"headers": {},
"queryParams": {
"APPID": "c3366d78c7c0f76d63eb4cdf1384ddbf",
"units": "metric",
"q": "[[${memory.current.input}]]"
},
"method": "get",
"contentType": "",
"body": ""
}
}
]
}{
"access-control-allow-origin": "*",
"date": "Sun, 13 May 2018 19:13:52 GMT",
"access-control-allow-headers": "authorization, Content-Type",
"content-length": "0",
"location": "eddi://ai.labs.httpcalls/httpcallsstore/httpcalls/5af88e70ba31c023bcb9ef2e?version=1",
"access-control-allow-methods": "GET, PUT, POST, DELETE, PATCH, OPTIONS",
"access-control-expose-headers": "location",
"content-type": null
}{
"outputSet": [
{
"action": "ask_for_city",
"timesOccurred": 0,
"outputs": [
{
"valueAlternatives": [
{
"type": "text",
"text": "Which City would you like to know the weather of?"
}
]
}
]
},
{
"action": "current_weather_in_city",
"timesOccurred": 0,
"outputs": [
{
"valueAlternatives": [
{
"type": "text",
"text": "The current weather situation of [[${memory.current.input}]] is [[${memory.current.httpCalls.currentWeather.weather[0].description}]] at [[${memory.current.httpCalls.currentWeather.main.temp}]] °C"
}
]
}
]
}
]
}{
"access-control-allow-origin": "*",
"date": "Sun, 13 May 2018 16:48:37 GMT",
"access-control-allow-headers": "authorization, Content-Type",
"content-length": "0",
"location": "eddi://ai.labs.output/outputstore/outputsets/5af86c65ba31c023bcb9ef2d?version=1",
"access-control-allow-methods": "GET, PUT, POST, DELETE, PATCH, OPTIONS",
"access-control-expose-headers": "location",
"content-type": null
}{
"packageExtensions": [
{
"type": "eddi://ai.labs.parser",
"extensions": {
"dictionaries": [
{
"type": "eddi://ai.labs.parser.dictionaries.integer"
},
{
"type": "eddi://ai.labs.parser.dictionaries.decimal"
},
{
"type": "eddi://ai.labs.parser.dictionaries.punctuation"
},
{
"type": "eddi://ai.labs.parser.dictionaries.email"
},
{
"type": "eddi://ai.labs.parser.dictionaries.time"
},
{
"type": "eddi://ai.labs.parser.dictionaries.ordinalNumber"
},
{
"type": "eddi://ai.labs.parser.dictionaries.regular",
"config": {
"uri": "eddi://ai.labs.regulardictionary/regulardictionarystore/regulardictionaries/{{dictionary_id}}?version=1"
}
}
],
"corrections": [
{
"type": "eddi://ai.labs.parser.corrections.stemming",
"config": {
"language": "english",
"lookupIfKnown": "false"
}
},
{
"type": "eddi://ai.labs.parser.corrections.levenshtein",
"config": {
"distance": "2"
}
},
{
"type": "eddi://ai.labs.parser.corrections.mergedTerms"
}
]
},
"config": {}
},
{
"type": "eddi://ai.labs.behavior",
"config": {
"uri": "eddi://ai.labs.behavior/behaviorstore/behaviorsets/{{behaviourset_id}}?version=1"
}
},
{
"type": "eddi://ai.labs.httpcalls",
"config": {
"uri": "eddi://ai.labs.httpcalls/httpcallsstore/httpcalls/{{httpcall_id}}?version=1"
}
},
{
"type": "eddi://ai.labs.output",
"config": {
"uri": "eddi://ai.labs.output/outputstore/outputsets/{{outputset_id}}?version=1"
}
},
{
"type": "eddi://ai.labs.templating",
"extensions": {},
"config": {}
}
]
}{
"access-control-allow-origin": "*",
"date": "Sun, 13 May 2018 19:26:36 GMT",
"access-control-allow-headers": "authorization, Content-Type",
"content-length": "0",
"location": "eddi://ai.labs.package/packagestore/packages/5af8916cba31c023bcb9ef2f?version=1",
"access-control-allow-methods": "GET, PUT, POST, DELETE, PATCH, OPTIONS",
"access-control-expose-headers": "location",
"content-type": null
}{
"packages": [
"eddi://ai.labs.package/packagestore/packages/{{package_id}}?version=1"
],
"channels": []
}{
"access-control-allow-origin": "*",
"date": "Sun, 13 May 2018 21:18:16 GMT",
"access-control-allow-headers": "authorization, Content-Type",
"content-length": "0",
"location": "eddi://ai.labs.bot/botstore/bots/5af8ab98ba31c023bcb9ef32?version=1",
"access-control-allow-methods": "GET, PUT, POST, DELETE, PATCH, OPTIONS",
"access-control-expose-headers": "location",
"content-type": null
}{
"access-control-allow-origin": "*",
"date": "Sun, 13 May 2018 21:21:54 GMT",
"access-control-allow-headers": "authorization, Content-Type",
"content-length": "0",
"access-control-allow-methods": "GET, PUT, POST, DELETE, PATCH, OPTIONS",
"access-control-expose-headers": "location",
"content-type": null
}{
"access-control-allow-origin": "*",
"date": "Sun, 13 May 2018 21:30:45 GMT",
"access-control-allow-headers": "authorization, Content-Type",
"content-length": "0",
"location": "eddi://ai.labs.conversation/conversationstore/conversations/5af8ae85ba31c023bcb9ef35",
"access-control-allow-methods": "GET, PUT, POST, DELETE, PATCH, OPTIONS",
"access-control-expose-headers": "location",
"content-type": null
}{
"input": "weather"
}{
"botId": "5af8b075ba31c023bcb9ef3b",
"botVersion": 1,
"environment": "unrestricted",
"conversationState": "READY",
"redoCacheSize": 0,
"conversationSteps": [
{
"conversationStep": [
{
"key": "input:initial",
"value": "weather"
},
{
"key": "actions",
"value": [
"ask_for_city"
]
},
{
"key": "output:text:ask_for_city",
"value": "Which City would you like to know the weather of?"
}
],
"timestamp": 1526247548410
}
]
}{
"access-control-allow-origin": "*",
"date": "Sun, 13 May 2018 21:35:15 GMT",
"content-type": "application/json;resteasy-server-has-produces=true",
"access-control-allow-headers": "authorization, Content-Type",
"content-length": "325",
"access-control-allow-methods": "GET, PUT, POST, DELETE, PATCH, OPTIONS",
"access-control-expose-headers": "location"
}{
"botId": "5af8b075ba31c023bcb9ef3b",
"botVersion": 1,
"environment": "unrestricted",
"conversationState": "READY",
"redoCacheSize": 0,
"conversationSteps": [
{
"conversationStep": [
{
"key": "input:initial",
"value": "Vienna"
},
{
"key": "actions",
"value": [
"current_weather_in_city"
]
},
{
"key": "output:text:current_weather_in_city",
"value": "The current weather situation of Vienna is clear sky at 17.68 °C"
}
],
"timestamp": 1526247618080
}
]
}{
"access-control-allow-origin": "*",
"date": "Sun, 13 May 2018 21:35:15 GMT",
"content-type": "application/json;resteasy-server-has-produces=true",
"access-control-allow-headers": "authorization, Content-Type",
"content-length": "325",
"access-control-allow-methods": "GET, PUT, POST, DELETE, PATCH, OPTIONS",
"access-control-expose-headers": "location"
}