general-runtime

general-runtime
is an http webhook service that handles voiceflow prototype requests and generates a response. It manages the state of the user based on the programs (flows) made on the Voiceflow Creator tool.
⚠️ This repository is still undergoing active development: Major breaking changes may be pushed periodically and the documentation may become outdated - a stable version has not been released
How interaction works
A Context
can consist of the request
, the state
, the config
, and the trace
.
request
is an object representing something the user has donestate
is the user metadata - what block they are currently on, what flow they are on, their variablesconfig
contains options for what should be returnedtrace
is an list of things for whatever client is calling the general-runtime
to show
The general-runtime
receives a Context
without trace
, and responds with a Context
with trace
. Here's what it looks like from the Voiceflow creator app prototype tool:
- User says/types something to the client, add the
request
to the Context
and sends it via webhook to general-runtime
- Fetch project version data based on env file
- Fetch the current program (flow) that the user is on based on env file
- Go through each block and update the user
state
, if the user enters a new flow, go back to step 3. - Generate a
Context
based on the final user state, send back to prototype tool - Client interprets response and presents it to the user
Repeat all steps each time a user speaks/types to the prototype tool, to perform a conversation.
Let's take a look at this interaction: the blue user text is the request.

The simplified example request Context
{
"request": {
"type": "text",
"payload": "What is the balance in my chequing account"
},
"state": {
"stack": [{
programID: "home flow",
nodeID: "prompt node"
}],
"storage": {},
"variables": {
"chequing_balance": null
}
}
}
The simplified example response Context
{
"request": {
"type": "intent",
"payload": {
"name": "check_balance_intent",
"entities": {
"name": "account",
"value": "chequing"
}
"query": "What is the balance in my chequing account"
}
},
"state": {
"stack": [{
programID: "home flow",
nodeID: "yes no choice node"
}],
"storage": {},
"variables": {
"balance": 0
}
},
"trace": [{
"type": "speak",
"payload": {
"type": "message",
"message": "the balance in your chequing account is 0 dollars, is that all?"
},
}, {
"type": "choice",
"payload": {
"choices": [{"name": "yes"}, {"name": "no"}]
}
}],
}
Notice that the text request
got processed by the NLP handler to become an intent type request
.
The state
is updated, and a trace
is generated.
To use the endpoint without the creator app prototype tool or the Runtime Client JavaScript SDK, you can start a conversation by hitting the /interact/{VERSION_ID}
with no request body. This will generate the state for you, which you can save. To move the conversation forward, you can create a GeneralRequest
object with your request and pass it in the response body to /interact/{VERSION_ID}
along with the state and optionally a Config
object. This will return an updated State
, a processed GeneralRequest
, and the GeneralTrace[]
list containing the traces to display.
Context Definition
A Context
can consist of the request
, the state
, the config
, and the trace
.
Type | Purpose | Definition | Example |
---|
GeneralRequest | An object representing something the user has done. | TextRequest | IntentRequest | DataRequest | null | { "type": "text", "payload": "What is my balance?" } |
State | The user metadata - what block they are currently on, what flow they are on, their variables. | { turn?: StorageState; stack: FrameState[]; storage: StorageState; variables: StorageState; } | { "stack": [{ programID: "home flow", nodeID: "prompt node" }], "storage": {}, "variables": { "chequing_balance": null } } |
Config | Contains options for what should be returned. | { tts?: boolean; } | { tts: false; } |
GeneralTrace | Things that the client is calling general-runtime to show. | BlockTrace | ChoiceTrace | DebugTrace | EndTrace | FlowTrace | AudioTrace | SpeakTrace | VisualTrace | { "type": "speak", "payload": { "type": "message", "message": "your balance is 0 dollars." } } |
Interact endpoint
To make requests to these endpoints, an API key will need to be passed in the Authorization
request header. For instructions on how to create an API key, see here.
Endpoint | Request Payload | Response Payload |
---|
GET /interact/{VERSION_ID}/state | {} | { ...state: State; } |
POST /interact/{VERSION_ID} | { state?: State; request?: GeneralRequest; config?: Config; } | { state: State; request: GeneralRequest; trace: GeneralTrace[]; } |
Setup
run yarn
in command line to install all dependencies.
Add the following file to the local repository:
.env.local
PORT=4000
LOG_LEVEL="info"
MIDDLEWARE_VERBOSITY="none"
GENERAL_SERVICE_ENDPOINT='https://general-service.voiceflow.com'
INTEGRATIONS_HANDLER_ENDPOINT="none"
CREATOR_API_ENDPOINT='https://api.voiceflow.com'
CREATOR_API_AUTHORIZATION='[YOUR JWT TOKEN HERE]'
# uncomment PROJECT_SOURCE to use local file
# PROJECT_SOURCE='file.vfr'
For more info on Environment Variables
API Documentation (Open API)
Documentation for all API Endpoints on this service.
It is critical to make sure our OpenAPI docs are up to date:
https://github.com/voiceflow/general-runtime/tree/master/backend/docs/openapi.yaml
Whenever any of the paths change, or new ones get added, or if any of the behaviors documented change, be sure to update the Open API doc.
We recommend using an editor like Swagger Editor or Stoplight to help construct your YAML file, and then fine tune things on local.
Local Setup
Run npm i -g redoc-cli
to install as command.
While on the root of this repository, run
redoc-cli serve backend/docs/openapi.yaml --ssr --watch
to see it locally - note: this will not load the local CSS file.
If your browser autoresolves http://localhost to https://localhost, you might want to open the local link in incognito or a different browser.
Notable Code Locations
Documentation
Context Handlers - handlers for processing request
lib/services/runtime/handlers - handlers for all the various blocks and defining their behavior