Metadata-Version: 2.4
Name: abtree
Version: 0.1.1
Summary: 异步行为树框架 - 现代化、模块化、易于集成的异步行为树框架
Author-email: aipanda <iepanda@outlook.com>
License: MIT License
        
        Copyright (c) 2025 Wenchang Xiong
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
Project-URL: Homepage, https://github.com/abtree/abtree
Project-URL: Repository, https://github.com/abtree/abtree
Project-URL: Documentation, https://abtree.readthedocs.io
Project-URL: Issues, https://github.com/abtree/abtree/issues
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.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: asyncio
Requires-Dist: typing-extensions>=4.0.0
Requires-Dist: lxml>=4.6.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
Requires-Dist: black>=22.0.0; extra == "dev"
Requires-Dist: isort>=5.0.0; extra == "dev"
Requires-Dist: mypy>=1.0.0; extra == "dev"
Requires-Dist: flake8>=5.0.0; extra == "dev"
Requires-Dist: bandit>=1.7.0; extra == "dev"
Requires-Dist: safety>=2.0.0; extra == "dev"
Requires-Dist: pip-tools>=7.0.0; extra == "dev"
Provides-Extra: cli
Requires-Dist: click>=8.0.0; extra == "cli"
Requires-Dist: rich>=12.0.0; extra == "cli"
Dynamic: license-file

# ABTree - Asynchronous Behavior Tree Framework

[![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)

ABTree (Asynchronous Behavior Tree) is a high-performance asynchronous behavior tree framework built on Python asyncio, supporting concurrent, sequential, conditional logic, and various control mechanisms. The framework includes built-in blackboard mechanism and asynchronous event system for cross-node data sharing and module decoupling. It supports import/export of behavior tree structures for visual configuration and system integration, helping to build flexible and extensible intelligent decision-making systems.

## ✨ Core Features

- 🚀 **Asynchronous Execution**: Asynchronous node scheduling based on `asyncio`, supporting concurrent and sequential control
- 🧩 **Modular Architecture**: Support for custom node type registration and dynamic construction
- 📊 **Blackboard System**: Built-in cross-node data sharing mechanism
- 🎯 **Event System**: Support for event listening and context awareness
- 📝 **XML Support**: Support for loading and exporting behavior trees from XML files
- 🛠️ **CLI Tools**: Command-line tools for debugging and testing

## 🚀 Quick Start

### Installation

```bash
pip install abtree
```

### Basic Usage

#### Method 1: Programmatic Construction

```python
import asyncio
from abtree import BehaviorTree, Sequence, Selector, Action, Condition
from abtree.core import Status

# Define action nodes
class OpenDoor(Action):
    async def execute(self, blackboard):
        print("Opening door")
        return Status.SUCCESS

class CloseDoor(Action):
    async def execute(self, blackboard):
        print("Closing door")
        return Status.SUCCESS

class ChangeBattery(Action):
    async def execute(self, blackboard):
        print("Automatically changing battery")
        return Status.SUCCESS

# Define condition nodes
class IsDoorOpen(Condition):
    async def evaluate(self, blackboard):
        return blackboard.get("door_open", False)

class IsBatteryLow(Condition):
    async def evaluate(self, blackboard):
        battery_level = blackboard.get("battery_level", 100)
        return battery_level < 20

# Build behavior tree
root = Selector("Robot Decision")
root.add_child(Sequence("Door Control Sequence"))
root.children[0].add_child(IsDoorOpen("Check Door Status"))
root.children[0].add_child(CloseDoor("Close Door"))

root.add_child(Sequence("Battery Change Sequence"))
root.children[1].add_child(IsBatteryLow("Check Battery Level"))
root.children[1].add_child(ChangeBattery("Change Battery"))

# Create behavior tree instance
tree = BehaviorTree(root)

# Execute
async def main():
    blackboard = tree.blackboard
    blackboard.set("door_open", True)
    blackboard.set("battery_level", 15)
    
    result = await tree.tick()
    print(f"Execution result: {result}")

asyncio.run(main())
```

#### Method 2: Load from XML String

```python
import asyncio
from abtree import load_from_xml_string, Status

# Define XML string
xml_string = '''<BehaviorTree name="Robot Decision" description="Simple robot behavior tree">
    <Selector name="Robot Decision">
        <Sequence name="Door Control Sequence">
            <CheckBlackboard name="Check Door Status" key="door_open" expected_value="true" />
            <Log name="Close Door Log" message="Door detected open, preparing to close" />
            <Wait name="Close Door Wait" duration="1.0" />
        </Sequence>
        <Sequence name="Battery Change Sequence">
            <Log name="Battery Change Log" message="Checking battery status" />
            <Wait name="Battery Change Wait" duration="2.0" />
        </Sequence>
    </Selector>
</BehaviorTree>'''

# Load behavior tree from XML string
tree = load_from_xml_string(xml_string)

# Execute
async def main():
    blackboard = tree.blackboard
    blackboard.set("door_open", True)
    
    result = await tree.tick()
    print(f"Execution result: {result}")

asyncio.run(main())
```

#### Method 3: Complex XML Configuration Example

```python
import asyncio
from abtree import load_from_xml_string, Status

# Complex robot AI XML configuration
xml_string = '''<BehaviorTree name="Robot AI" description="Intelligent robot behavior tree">
    <Selector name="Main Decision">
        <!-- Door control branch -->
        <Sequence name="Door Control Sequence">
            <CheckBlackboard name="Check Door Status" key="door_open" expected_value="true" />
            <Compare name="Check Door Sensor" key="door_sensor" operator="==" value="true" />
            <Log name="Start Closing Door" message="Door detected open, preparing to close!" />
            <Wait name="Close Door Delay" duration="0.5" />
            <SetBlackboard name="Set Door Closing Status" key="is_closing_door" value="true" />
        </Sequence>
        
        <!-- Patrol branch -->
        <Sequence name="Patrol Sequence">
            <CheckBlackboard name="Check Door Closed" key="door_open" expected_value="false" />
            <Log name="Start Patrol" message="Door closed, starting patrol..." />
            <Wait name="Patrol Time" duration="2.0" />
            <SetBlackboard name="Set Patrol Status" key="is_patrolling" value="true" />
        </Sequence>
        
        <!-- Battery change branch -->
        <Sequence name="Battery Change Sequence">
            <Compare name="Check Battery Level" key="battery_level" operator="&lt;=" value="20" />
            <Log name="Start Battery Change" message="Battery level low, preparing to change battery..." />
            <Wait name="Battery Change Time" duration="3.0" />
            <SetBlackboard name="Replenish Battery" key="battery_level" value="100" />
        </Sequence>
    </Selector>
</BehaviorTree>'''

# Load behavior tree from XML string
tree = load_from_xml_string(xml_string)

# Execute
async def main():
    blackboard = tree.blackboard
    blackboard.set("door_open", True)
    blackboard.set("battery_level", 15)
    
    for i in range(3):
        result = await tree.tick()
        print(f"Tick {i+1}: {result}")
        print(f"Status: Closing door={blackboard.get('is_closing_door')}, Patrolling={blackboard.get('is_patrolling')}")

asyncio.run(main())
```

## 📚 Documentation

- [API Documentation](docs/api.md)
- [Example Code](docs/examples.md)
- [CLI Tool Usage](docs/cli.md)

## 🛠️ Development

### Install Development Dependencies

```bash
pip install -e ".[dev]"
```

### Run Tests

```bash
pytest tests/
```

### Code Formatting

```bash
black abtree/
isort abtree/
```

## 📄 License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

## 🤝 Contributing

Welcome to submit Issues and Pull Requests!

## 📞 Contact

- Project Homepage: https://github.com/abtree/abtree
- Issue Feedback: https://github.com/abtree/abtree/issues 
