____ __ __ _____ _____ / _ \____ __ ______ ______/ /_____/ /___ /_ _\ /_ _\ / /_/ / __ \/ / / / __ \/ ___\, / __ \, / __ \ 0> 0> <0 <0 / ,\ ,/ /_/ /\ \/ / /_/ /\__, / / /_/ / / /_/ / \__⊽__/ \__⊽__/ \/ \/\__/\/ \__/ ,___/\____/\/\__/\/\/ ,___/ ⋂ - Hey! ⋂ \____/ \____/ Olà! -
Ravestate is a reactive library for real-time natural language dialog systems. It combines elements from event-based and reactive programming into an API, where application states are defined as functions that are run when a certain boolean set of criteria (signals) in the current application context is satisfied. It is the first reactive API to allow for boolean combinations of events. You may find a short introductory video here.
Pretty docs can be found at roboy.github.io/ravestate.
Reactive Hello World
import ravestate as rs # We want to write some text output, so we # need the raw:out context property from ravestate_rawio. import ravestate_rawio as rawio # Make sure that we use some i/o implementation, # so we can actually see stuff that is written to rawio:out. import ravestate_conio as conio # Ravestate applications should always be wrapped in a Module. # This allows easier scoping, and enables separation of concerns # beyond states. with rs.Module(name="hi!", depends=(rawio.mod, conio.mod)): # Create an application state which reacts to the `:startup` signal, # and writes a string to raw:out. Note: State functions are # always run asynchronously! @rs.state(cond=rs.sig_startup, write=rawio.prop_out) def hello_world(context): context[rawio.prop_out] = "Waddup waddup waddup!" # Run context with console input/output and our 'hi!' module. rs.Context("hi!", "conio").run()
Ravestate has an angular/socket.io-based interactive (beta) UI called Raveboard. It shows the events (spikes) that are currently relevant, as well as potential state activations that are referencing these spikes.
raveboard.UIContext instead of
python3 -m raveboard instead of
python3 -m ravestate, a real-time visualization of all spikes/activations, as well as a chat window,
will be hosted on a configurable port. You can find dedicated docs here.
The following GIF shows raveboard together with ravestate_visionio:
The easiest way to install ravestate is through pip:
pip install ravestate
Note: Ravestate requires Python 3.6 or higher. It is tested on Ubuntu 18.04 and 20.04, as well as macOS > High Sierra. It is currently not tested on Windows, but seems to run fine in WSL2.
Ravestate offers a docker image that bundles runtime dependencies that are required for advanced cognitive dialog systems/chatbots:
📦Neo4j: The Neo4j Graph DBMS is used by Scientio for long-term memory.
💡Redis: A Redis in-memory DB is used for fast short-term memory, e.g. to store/recall facial feature vectors.
🤦FaceOracle: A Roboy-developed server-client architecture used by
ravestate_visioniofor real-time face recognition.
🤖ROS Melodic: Version 1 of the Robot Operating System for distributed real-time communication. This version of ROS requires a broker process (
roscore), which is started automatically inside the container.
🤖ROS2 Dashing: Version 2 of the Robot Operating System for distributed real-time communication.
🤗HuggingFace Transformer Models: Language models (ConvAI GPT/OpenAI GPT2) for neural-network-generated conversation.
💌Roboy ROS Messages: Message defs. that are required to interact with Roboy hardware.
Installing these dependencies by hand is time-consuming and error-prone, so using Docker to ship them makes everyone's lives easier!
How to get?
Option 1: Pulling from Dockerhub
docker pull realitivity/ravestate
Note: You will still need to clone ravestate for the docker-compose file.
Option 2: Building the image yourself
git clone firstname.lastname@example.org:roboy/ravestate && cd ravestate
You can build the ravestate container using the provided
docker build -t realitivity/ravestate .
Note: Building the container takes time and requires a good internet connection, since all of the dependencies are several Gigabytes in size.
How to run?
Use one of the following docker-compose commands to run ravestate in Docker:
|Windows||Not supported yet.|
The container is now running and a shell inside the container can be opened with:
docker exec -it rs bash
You can now start ravestate or raveboard as described in the section Running Hello World.
python3 -m ravestate [...]
Which services are exposed from the container?
|Neo4j UI||7474||Neo4j UI for DB stored under
|Neo4j Bolt Interface||7687||Communication with Neo4j DBMS|
|Redis Database Dump||-||A dump of the Redis DB in the container can be found under
|FaceOracle Client Interface||8088||Visualisation for the FaceOracle client.|
|Raveboard||42424||Default port for raveboard, the ravestate debug UI.|
Initial configuration and setup
Step 1: Clone the repository and install dependencies:
cd ~ # Create a virtual python environment to not pollute the global setup python3 -m virtualenv -p python3 python-ravestate # Source the virtual environment . python-ravestate/bin/activate # Clone the repo git clone email@example.com:roboy/ravestate && cd ravestate # Install normal requirements pip install -r requirements.txt # To run tests & build docs, install pytest, mocking, fixtures, pydoc, ... pip install -r requirements-dev.txt # Link your local ravestate clone into your virtualenv pip install -e .
Step 2: Launch the ravestate docker container as described above. It will serve you Neo4j, which is a backend for Scientio, Roboy's long-term memory system.
Step 3: In the
config folder, create a file called
keys.yml. This is where your secrets,
such as database credentials or your telegram token will go. For example,:
module: telegramio config: telegram-token: <sexycactus> # This is where your own telegram bot token # will go later
Step 4: You may now conduct your first conversation with ravestate:
python3 -m raveboard -f config/generic.yml -f config/keys.yml
Open raveboard on
to conduct your first conversation with ravestate.
After the conversation, check the Neo4j interface under
localhost:7474. It should now contain some nodes!
Reminder: Whenever you use ravestate from the command line, source the virtual environment first!
Running your Telegram bot
To test your telegram bot with a custom bot token in your
telegram_test.yml instead of
generic.yml. This will load the
Setting up PyCharm
- Open your local ravestate clone as a project in pycharm.
Project Preferences > Python interpreter, set your virtual environment.
- Mark the
modulesfolder as sources root via the right-click context menu.
- Create a run config via the "Edit configurations menu":
• Create a new Python configuration.
raveboardas the module to execute
• Set the working directory to the git clone directory.
• Set parameters to
-f config/generic.yml -f config/keys.yml.
- You should now be able to run the generic ravestate config from PyCharm.
Running Hello World
Ravestate applications are defined by a configuration, which specifies the ravestate modules that should be loaded.
To run the basic hello world application, run ravestate with a config file or command line arguments:
Running with command line spec
You can easily run a combination of ravestate modules in a shared context,
by listing them as arguments to
python3 -m ravestate:
python3 -m ravestate \ ravestate_wildtalk \ ravestate_conio \ ravestate_hibye \ ravestate_persqa
python3 -m ravestate -h to see more options!
Running with config file(s)
You may specify a series of config files to configure ravestate context, when specifying everything through the command line becomes too laborious:
# In file hello_world.yml module: core config: import: - ravestate_wildtalk - ravestate_conio - ravestate_hibye - ravestate_persqa
ravestate with this config file:
python3 -m ravestate -f hello_world.yml
Ravestate offers a landscape of fine-grained modules for different aspects of dialog application tasks, which may be seen in the following dependency diagram. Broadly, the modules are categorized into Core (Blue), I/O (Yellow), External (Red) and Skills (Green):
|ravestate||Core ravestate library.|
|ravestate_ontology||Connects to scientio to serve a built-in ontology.|
|ravestate_verbaliser||Utilities for easy management of conversational text, documented here.|
|ravestate_nlp||Spacy-based NLP properties and signals, documented here.|
|ravestate_emotion||Generates signals for, and recognizes specific emotions (
|ravestate_conio||Simple command-line based IO for development purposes.|
|ravestate_telegramio||Single- or Multi-process Telegram server module, documented here.|
|ravestate_roboyio||PyroBoy -based STT/TTS with ROS2.|
|ravestate_visionio||See dedicated docs here. Enables face-recognition based dialog interactions.|
|ravestate_wildtalk||See docs here - runs generative language models (GPT-2, ConvAi, ParlAi)!|
|ravestate_hibye||Simply voices Hi! (or the likes thereof) when an interlocutor is added, and Bye when one is removed.|
|ravestate_persqa||Conducts personalized smalltalk with interlocutors, interacts with Scientio to persist trivia.|
|ravestate_genqa||DrQA -based general question answering module.|
|ravestate_roboyqa||QA module which provides answers to questions about Roboy, such as Who is your dad?|
|ravestate_akinator (*)||Enables dialog-based play of Akinator!|
|ravestate_sendpics (*)||Uses face recognition to extract facial features and an assiciated Person with
|ravestate_fillers||Recognize when the dialog context is taking a long time to produce an answer, and voice a filler like "Uhm" or "Let's see...".|
Note: (*) = deprecated.
If you have built the ravestate docker image as described above, you may run the test suite as follows:
docker run -t -v $(pwd):/ravestate -w /ravestate realitivity/ravestate ./run_tests.sh
Building/maintaining the docs
If you have installed the dependencies from
generate the docs by running this command at project root:
export PYTHONPATH=$PYTHONPATH:$(pwd)/modules git rm -rf docs rm -rf _build docs pydocmd build mkdir -p docs/resources/docs && cp resources/docs/*.png docs/resources/docs && cp resources/docs/*.gif docs/resources/docs git add docs/* # For inspection: python3 -m http.server --directory docs
The structure and content of the docs are defined in the file