Action decomposition and execution framework
Project description
Action Trees
Documentation: https://roxautomation.gitlab.io/action-trees
Source Code: https://gitlab.com/roxautomation/action-trees
Summary
Action Trees is a Python framework for orchestrating hierarchical, asynchronous actions. It enables the structuring of complex processes into manageable, interdependent tasks that can be executed sequentially or in parallel, simplifying the management and execution of multi-step workflows.
Action Trees vs. Behavior Trees
Behavior Trees (BTs) and Action Trees (ATs) use a tree-like structure but have different goals. BTs make choices about what to do next based on current situations, which is great for tasks needing quick decisions. ATs are about executing complex tasks efficiently, with a focus on robust error-handling errors and asynchronous operation. In short, BTs are for making decisions, while ATs are for carrying out tasks effectively.
Example - Coffee maker
Let's simulate a coffee-making machine using the following action hierarchy:
- cappuccino_order
- prepare
- initialize
- clean
- make_cappuccino
- boil_water
- grind_coffee
An implementation would look like this:
import asyncio
from action_trees import ActionItem
class AtomicAction(ActionItem):
"""Basic machine action with no children."""
def __init__(self, name: str, duration: float = 0.1):
super().__init__(name=name)
self._duration = duration
async def _on_run(self):
await asyncio.sleep(self._duration)
class PrepareMachineAction(ActionItem):
"""Prepare the machine."""
def __init__(self):
super().__init__(name="prepare")
self.add_child(AtomicAction(name="initialize"))
self.add_child(AtomicAction(name="clean"))
async def _on_run(self):
# sequentially run children
await self.get_child("initialize").start()
await self.get_child("clean").start()
class MakeCappuccinoAction(ActionItem):
"""Make cappuccino."""
def __init__(self):
super().__init__(name="make_cappuccino")
self.add_child(AtomicAction(name="boil_water"))
self.add_child(AtomicAction(name="grind_coffee"))
async def _on_run(self):
# simultaneously run children
await self.start_children_parallel()
class CappuccinoOrder(ActionItem):
"""High-level action to make a cappuccino."""
def __init__(self):
super().__init__(name="cappuccino_order")
self.add_child(PrepareMachineAction())
self.add_child(MakeCappuccinoAction())
async def _on_run(self):
for child in self.children:
await child.start()
# create root order
order = CappuccinoOrder()
# start tasks in the background
await order.start()
Development
Please develop inside the container, this will ensure all the required checks (pylint
& mypy
) as well as formatting (black
)
If you are not familiar with devcontainers, read Developing inside a Container first
- Clone this repository
- open dir in VS Code
vscode .
- rebuild and reopen in container (you'll need
Dev Containers
extension)
note: if a container with devcontainer
name already exists, an error will occur. You can remove it with
docker container prune -f
What goes where
gitlab-ci.yml
- gitlab ci scriptinit_container.sh
script to initialize container for development.setup.py
- main packge setup filedocs
- documentation, uses mkdocsinstall
- scripts for preparing host system
Version control
Version control is done with git tags using setuptools_scm
use git tag v1.2.3
to update version number. Use git describe
to show current version.
Documentation
The documentation is automatically generated from the content of the docs directory and from the docstrings of the public signatures of the source code.
run serve_docs.sh
from inside the container to build and serve documentation.
note: pyreverse
creates images of packages and classes in docs/uml/..
Pre-commit
optional. Add precommit install
to init_container.sh
if required.
This project was forked from cookiecutter template template.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file action_trees-0.3.1.tar.gz
.
File metadata
- Download URL: action_trees-0.3.1.tar.gz
- Upload date:
- Size: 88.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.12.1
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 9838d749497b96b04d3d0e3148f24206d270675501f3329991df6b653dcc83f7 |
|
MD5 | a8b5d66d59b282d49cb0e6a05e74bd89 |
|
BLAKE2b-256 | fc1339535cb0d3888f193df14bfb68872bce2e269d6198e9477073be635a7397 |
File details
Details for the file action_trees-0.3.1-py3-none-any.whl
.
File metadata
- Download URL: action_trees-0.3.1-py3-none-any.whl
- Upload date:
- Size: 10.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.12.1
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 2f876b447faceb894595438932c5b1de15ae41ee217660cb863b0b0d2ac474c0 |
|
MD5 | 1d63a314bfa0b51e991b42da7e3d6afc |
|
BLAKE2b-256 | 9d85f2451e8b38e362731ce8c681430367769e96cd9341fe04c1d9e6f25286bc |