Metadata-Version: 2.4
Name: bonsai-bt
Version: 0.12.0
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Rust
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Games/Entertainment
Classifier: Typing :: Typed
Summary: Behavior trees in Python, powered by the bonsai-bt Rust crate.
Home-Page: https://github.com/sollimann/bonsai
Author-email: Kristoffer Solberg Rakstad <solkristoffer@gmail.com>, Anmol Kathail <anmolkathail@gmail.com>
License: MIT
Requires-Python: >=3.10
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: Homepage, https://github.com/sollimann/bonsai
Project-URL: Issues, https://github.com/sollimann/bonsai/issues
Project-URL: Repository, https://github.com/sollimann/bonsai

# bonsai-bt - Python bindings

Python bindings for the [bonsai-bt](https://github.com/sollimann/bonsai)
behavior-tree library.

## Installation (dev)

```bash
python -m venv .venv
source .venv/bin/activate   # Windows: .venv\Scripts\Activate.ps1
pip install maturin
cd bonsai-py
maturin develop
python -c "import bonsai_bt; print(bonsai_bt.__version__)"
```

## Same BT in Rust and Python

A minimal three-node tree (`Hello → Wait(1.0) → Goodbye`) implemented in both languages. Semantics are identical because the Python package is a thin wrapper around the Rust crate; only the API surface differs (Rust requires an `enum` + explicit types; Python uses any hashable object as the action payload).

### Rust

```rust
use bonsai_bt::{Behavior, Event, Status, UpdateArgs, BT};

#[derive(Clone, Debug)]
enum Greet { Hello, Goodbye }

fn main() {
    let tree = Behavior::Sequence(vec![
        Behavior::Action(Greet::Hello),
        Behavior::Wait(1.0),
        Behavior::Action(Greet::Goodbye),
    ]);

    let mut bt: BT<Greet, ()> = BT::new(tree, ());

    for _ in 0..5 {
        let e: Event = UpdateArgs { dt: 0.5 }.into();
        bt.tick(&e, &mut |args, _bb| {
            match *args.action {
                Greet::Hello   => println!("hello"),
                Greet::Goodbye => println!("goodbye"),
            }
            (Status::Success, args.dt)
        });
    }
}
```

### Python

```python
import bonsai_bt as bt

tree = bt.Sequence([
    bt.Action("hello"),
    bt.Wait(1.0),
    bt.Action("goodbye"),
])

tree_bt = bt.BT(tree, None)

def cb(args, _bb):
    print(args.action)
    return (bt.Status.Success, args.dt)

for _ in range(5):
    tree_bt.tick(0.5, cb)
```

Output (both):

    hello
    goodbye

For richer examples — multi-job orchestration, visualizer integration, parallel agents — see [examples/](examples/).

## License

MIT - see [LICENSE](../LICENSE).

