autohd 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- autohd-0.1.0/LICENSE +21 -0
- autohd-0.1.0/PKG-INFO +192 -0
- autohd-0.1.0/README.md +144 -0
- autohd-0.1.0/autohd/__init__.py +24 -0
- autohd-0.1.0/autohd/benchmarks/__init__.py +41 -0
- autohd-0.1.0/autohd/benchmarks/base.py +134 -0
- autohd-0.1.0/autohd/benchmarks/blocksworld.py +154 -0
- autohd-0.1.0/autohd/benchmarks/game24.py +193 -0
- autohd-0.1.0/autohd/benchmarks/rubiks_cube.py +156 -0
- autohd-0.1.0/autohd/cli/__init__.py +5 -0
- autohd-0.1.0/autohd/cli/main.py +159 -0
- autohd-0.1.0/autohd/core/autohd.py +592 -0
- autohd-0.1.0/autohd/core/config.py +58 -0
- autohd-0.1.0/autohd/core/llm_client.py +147 -0
- autohd-0.1.0/autohd/integrations/__init__.py +8 -0
- autohd-0.1.0/autohd/integrations/langchain.py +141 -0
- autohd-0.1.0/autohd/search/__init__.py +48 -0
- autohd-0.1.0/autohd/search/astar.py +219 -0
- autohd-0.1.0/autohd/search/greedy_bfs.py +177 -0
- autohd-0.1.0/autohd.egg-info/PKG-INFO +192 -0
- autohd-0.1.0/autohd.egg-info/SOURCES.txt +26 -0
- autohd-0.1.0/autohd.egg-info/dependency_links.txt +1 -0
- autohd-0.1.0/autohd.egg-info/entry_points.txt +2 -0
- autohd-0.1.0/autohd.egg-info/requires.txt +24 -0
- autohd-0.1.0/autohd.egg-info/top_level.txt +1 -0
- autohd-0.1.0/pyproject.toml +93 -0
- autohd-0.1.0/setup.cfg +4 -0
- autohd-0.1.0/tests/test_autohd.py +126 -0
autohd-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 AutoHD Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
autohd-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: autohd
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Automated Heuristics Discovery for LLM Planning - Enable LLMs to generate and evolve heuristic functions for complex planning tasks
|
|
5
|
+
Author-email: Your Name <your.email@example.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/yourusername/autohd
|
|
8
|
+
Project-URL: Documentation, https://github.com/yourusername/autohd#readme
|
|
9
|
+
Project-URL: Repository, https://github.com/yourusername/autohd
|
|
10
|
+
Project-URL: Issues, https://github.com/yourusername/autohd/issues
|
|
11
|
+
Project-URL: Bug Tracker, https://github.com/yourusername/autohd/issues
|
|
12
|
+
Keywords: llm,planning,heuristics,reasoning,inference-time,autohd,test-time-compute
|
|
13
|
+
Classifier: Development Status :: 3 - Alpha
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Intended Audience :: Science/Research
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
23
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
24
|
+
Requires-Python: >=3.10
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
License-File: LICENSE
|
|
27
|
+
Requires-Dist: openai>=1.0.0
|
|
28
|
+
Requires-Dist: anthropic>=0.20.0
|
|
29
|
+
Requires-Dist: litellm>=1.0.0
|
|
30
|
+
Provides-Extra: dev
|
|
31
|
+
Requires-Dist: pytest>=8.0.0; extra == "dev"
|
|
32
|
+
Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
|
|
33
|
+
Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
|
|
34
|
+
Requires-Dist: black>=24.0.0; extra == "dev"
|
|
35
|
+
Requires-Dist: ruff>=0.3.0; extra == "dev"
|
|
36
|
+
Requires-Dist: mypy>=1.8.0; extra == "dev"
|
|
37
|
+
Requires-Dist: httpx>=0.27.0; extra == "dev"
|
|
38
|
+
Provides-Extra: cli
|
|
39
|
+
Requires-Dist: click>=8.0.0; extra == "cli"
|
|
40
|
+
Requires-Dist: rich>=13.0.0; extra == "cli"
|
|
41
|
+
Provides-Extra: langchain
|
|
42
|
+
Requires-Dist: langchain>=0.1.0; extra == "langchain"
|
|
43
|
+
Requires-Dist: langchain-core>=0.1.0; extra == "langchain"
|
|
44
|
+
Requires-Dist: langchain-openai>=0.0.5; extra == "langchain"
|
|
45
|
+
Provides-Extra: all
|
|
46
|
+
Requires-Dist: autohd[cli,dev,langchain]; extra == "all"
|
|
47
|
+
Dynamic: license-file
|
|
48
|
+
|
|
49
|
+
# AutoHD: Automated Heuristics Discovery for LLM Planning
|
|
50
|
+
|
|
51
|
+
[](https://pypi.org/project/autohd/)
|
|
52
|
+
[](https://www.python.org/downloads/)
|
|
53
|
+
[](https://github.com/yourusername/autohd/blob/main/LICENSE)
|
|
54
|
+
[](https://github.com/yourusername/autohd#readme)
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## What is AutoHD?
|
|
59
|
+
|
|
60
|
+
**AutoHD** (Automated Heuristics Discovery) is a Python package that enables LLMs to generate and evolve heuristic functions for guiding inference-time search in complex planning tasks.
|
|
61
|
+
|
|
62
|
+
Based on the research paper: ["Complex LLM Planning via Automated Heuristics Discovery"](https://arxiv.org/abs/2502.19295v1) (arXiv:2502.19295v1, Feb 2025, Texas A&M University).
|
|
63
|
+
|
|
64
|
+
### Key Features
|
|
65
|
+
|
|
66
|
+
- **LLM-Generated Heuristics**: LLMs automatically generate heuristic functions as Python code
|
|
67
|
+
- **Heuristic Evolution**: Iterative refinement through exploration and modification strategies
|
|
68
|
+
- **Multiple Search Algorithms**: Support for Greedy BFS and A* search
|
|
69
|
+
- **Multiple Planning Tasks**: Blocksworld, Game of 24, and Rubik's Cube
|
|
70
|
+
- **LLM-Agnostic**: Works with OpenAI, Anthropic, and other providers via litellm
|
|
71
|
+
- **LangChain Integration**: Plug into LangChain agents and chains
|
|
72
|
+
|
|
73
|
+
## Quick Start
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
pip install autohd
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Basic Usage
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
import asyncio
|
|
83
|
+
from autohd import AutoHD
|
|
84
|
+
from autohd.core.config import AutoHDConfig, LLMConfig
|
|
85
|
+
|
|
86
|
+
async def main():
|
|
87
|
+
# Configure AutoHD
|
|
88
|
+
config = AutoHDConfig(
|
|
89
|
+
task_name="blocksworld",
|
|
90
|
+
llm=LLMConfig(model="gpt-4o", provider="openai"),
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
# Initialize AutoHD
|
|
94
|
+
autohd = AutoHD(config=config)
|
|
95
|
+
|
|
96
|
+
# Generate synthetic training data
|
|
97
|
+
train_data = [
|
|
98
|
+
{"initial_state": "the red block is clear...", "goal_state": "the orange block is on top of the red block..."},
|
|
99
|
+
# ... more examples
|
|
100
|
+
]
|
|
101
|
+
|
|
102
|
+
# Run the pipeline
|
|
103
|
+
results = await autohd.run(
|
|
104
|
+
train_data=train_data,
|
|
105
|
+
test_data=test_data,
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
print(f"Best heuristic accuracy: {results['test_results']['accuracy']:.1%}")
|
|
109
|
+
|
|
110
|
+
asyncio.run(main())
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### CLI Usage
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
# Run on Blocksworld
|
|
117
|
+
autohd run --task blocksworld --model gpt-4o
|
|
118
|
+
|
|
119
|
+
# Run on Game of 24
|
|
120
|
+
autohd run --task game24 --model gpt-4o
|
|
121
|
+
|
|
122
|
+
# Run on Rubik's Cube
|
|
123
|
+
autohd run --task rubiks_cube --model gpt-4o
|
|
124
|
+
|
|
125
|
+
# Custom configuration
|
|
126
|
+
autohd run --task blocksworld --generations 5 --population 10 --search-algorithm astar
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Architecture
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
autohd/
|
|
133
|
+
├── core/ # Core framework
|
|
134
|
+
│ ├── autohd.py # Main AutoHD class
|
|
135
|
+
│ ├── config.py # Configuration classes
|
|
136
|
+
│ └── llm_client.py # LLM API abstraction
|
|
137
|
+
├── search/ # Search algorithms
|
|
138
|
+
│ ├── greedy_bfs.py # Greedy BFS solver
|
|
139
|
+
│ └── astar.py # A* solver
|
|
140
|
+
├── benchmarks/ # Planning task implementations
|
|
141
|
+
│ ├── base.py # Base benchmark class
|
|
142
|
+
│ ├── blocksworld.py # Blocksworld task
|
|
143
|
+
│ ├── game24.py # Game of 24 task
|
|
144
|
+
│ └── rubiks_cube.py # Rubik's Cube task
|
|
145
|
+
├── integrations/ # Framework integrations
|
|
146
|
+
│ └── langchain.py # LangChain integration
|
|
147
|
+
└── cli/ # Command-line interface
|
|
148
|
+
└── main.py # CLI entry point
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## How It Works
|
|
152
|
+
|
|
153
|
+
AutoHD follows a 5-step pipeline:
|
|
154
|
+
|
|
155
|
+
1. **Generate Initial Heuristics**: LLMs are prompted to create heuristic functions as Python code
|
|
156
|
+
2. **Evaluate Heuristics**: Each heuristic is tested on validation data using heuristic-guided search
|
|
157
|
+
3. **Evolve Heuristics**: Iterative refinement through exploration (new ideas) and modification (tweaking existing)
|
|
158
|
+
4. **Select Best**: The best heuristic from all generations is chosen
|
|
159
|
+
5. **Test**: The selected heuristic is evaluated on test data
|
|
160
|
+
|
|
161
|
+
## Performance
|
|
162
|
+
|
|
163
|
+
Based on the research paper:
|
|
164
|
+
|
|
165
|
+
| Task | GPT-4o-mini | GPT-4o | Llama 3.1 70B | Best Baseline |
|
|
166
|
+
|------|-------------|--------|---------------|---------------|
|
|
167
|
+
| Blocksworld | 42.4% | **75.1%** | 59.1% | ~2× improvement |
|
|
168
|
+
| Game of 24 | 54% | **70%** | 69% | vs ToT 42/62/59 |
|
|
169
|
+
| Rubik's Cube (2×2) | **82.5%** | **83.1%** | **84.7%** | vs XoT 67/80/78 |
|
|
170
|
+
|
|
171
|
+
## Requirements
|
|
172
|
+
|
|
173
|
+
- Python 3.10+
|
|
174
|
+
- OpenAI API key (or other LLM provider)
|
|
175
|
+
- Optional: `litellm` for multi-provider support
|
|
176
|
+
|
|
177
|
+
## License
|
|
178
|
+
|
|
179
|
+
MIT License
|
|
180
|
+
|
|
181
|
+
## Citation
|
|
182
|
+
|
|
183
|
+
If you use AutoHD in your research, please cite:
|
|
184
|
+
|
|
185
|
+
```
|
|
186
|
+
@article{ling2025autohd,
|
|
187
|
+
title={Complex LLM Planning via Automated Heuristics Discovery},
|
|
188
|
+
author={Ling, Hongyi and Parashar, Shubham and Khurana, Sambhav and Olson, Blake and Basu, Anwesha and Sinha, Gaurangi and Tu, Zhengzhong and Caverlee, James and Ji, Shuiwang},
|
|
189
|
+
journal={arXiv preprint arXiv:2502.19295},
|
|
190
|
+
year={2025}
|
|
191
|
+
}
|
|
192
|
+
```
|
autohd-0.1.0/README.md
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# AutoHD: Automated Heuristics Discovery for LLM Planning
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/autohd/)
|
|
4
|
+
[](https://www.python.org/downloads/)
|
|
5
|
+
[](https://github.com/yourusername/autohd/blob/main/LICENSE)
|
|
6
|
+
[](https://github.com/yourusername/autohd#readme)
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## What is AutoHD?
|
|
11
|
+
|
|
12
|
+
**AutoHD** (Automated Heuristics Discovery) is a Python package that enables LLMs to generate and evolve heuristic functions for guiding inference-time search in complex planning tasks.
|
|
13
|
+
|
|
14
|
+
Based on the research paper: ["Complex LLM Planning via Automated Heuristics Discovery"](https://arxiv.org/abs/2502.19295v1) (arXiv:2502.19295v1, Feb 2025, Texas A&M University).
|
|
15
|
+
|
|
16
|
+
### Key Features
|
|
17
|
+
|
|
18
|
+
- **LLM-Generated Heuristics**: LLMs automatically generate heuristic functions as Python code
|
|
19
|
+
- **Heuristic Evolution**: Iterative refinement through exploration and modification strategies
|
|
20
|
+
- **Multiple Search Algorithms**: Support for Greedy BFS and A* search
|
|
21
|
+
- **Multiple Planning Tasks**: Blocksworld, Game of 24, and Rubik's Cube
|
|
22
|
+
- **LLM-Agnostic**: Works with OpenAI, Anthropic, and other providers via litellm
|
|
23
|
+
- **LangChain Integration**: Plug into LangChain agents and chains
|
|
24
|
+
|
|
25
|
+
## Quick Start
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pip install autohd
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Basic Usage
|
|
32
|
+
|
|
33
|
+
```python
|
|
34
|
+
import asyncio
|
|
35
|
+
from autohd import AutoHD
|
|
36
|
+
from autohd.core.config import AutoHDConfig, LLMConfig
|
|
37
|
+
|
|
38
|
+
async def main():
|
|
39
|
+
# Configure AutoHD
|
|
40
|
+
config = AutoHDConfig(
|
|
41
|
+
task_name="blocksworld",
|
|
42
|
+
llm=LLMConfig(model="gpt-4o", provider="openai"),
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
# Initialize AutoHD
|
|
46
|
+
autohd = AutoHD(config=config)
|
|
47
|
+
|
|
48
|
+
# Generate synthetic training data
|
|
49
|
+
train_data = [
|
|
50
|
+
{"initial_state": "the red block is clear...", "goal_state": "the orange block is on top of the red block..."},
|
|
51
|
+
# ... more examples
|
|
52
|
+
]
|
|
53
|
+
|
|
54
|
+
# Run the pipeline
|
|
55
|
+
results = await autohd.run(
|
|
56
|
+
train_data=train_data,
|
|
57
|
+
test_data=test_data,
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
print(f"Best heuristic accuracy: {results['test_results']['accuracy']:.1%}")
|
|
61
|
+
|
|
62
|
+
asyncio.run(main())
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### CLI Usage
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# Run on Blocksworld
|
|
69
|
+
autohd run --task blocksworld --model gpt-4o
|
|
70
|
+
|
|
71
|
+
# Run on Game of 24
|
|
72
|
+
autohd run --task game24 --model gpt-4o
|
|
73
|
+
|
|
74
|
+
# Run on Rubik's Cube
|
|
75
|
+
autohd run --task rubiks_cube --model gpt-4o
|
|
76
|
+
|
|
77
|
+
# Custom configuration
|
|
78
|
+
autohd run --task blocksworld --generations 5 --population 10 --search-algorithm astar
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Architecture
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
autohd/
|
|
85
|
+
├── core/ # Core framework
|
|
86
|
+
│ ├── autohd.py # Main AutoHD class
|
|
87
|
+
│ ├── config.py # Configuration classes
|
|
88
|
+
│ └── llm_client.py # LLM API abstraction
|
|
89
|
+
├── search/ # Search algorithms
|
|
90
|
+
│ ├── greedy_bfs.py # Greedy BFS solver
|
|
91
|
+
│ └── astar.py # A* solver
|
|
92
|
+
├── benchmarks/ # Planning task implementations
|
|
93
|
+
│ ├── base.py # Base benchmark class
|
|
94
|
+
│ ├── blocksworld.py # Blocksworld task
|
|
95
|
+
│ ├── game24.py # Game of 24 task
|
|
96
|
+
│ └── rubiks_cube.py # Rubik's Cube task
|
|
97
|
+
├── integrations/ # Framework integrations
|
|
98
|
+
│ └── langchain.py # LangChain integration
|
|
99
|
+
└── cli/ # Command-line interface
|
|
100
|
+
└── main.py # CLI entry point
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## How It Works
|
|
104
|
+
|
|
105
|
+
AutoHD follows a 5-step pipeline:
|
|
106
|
+
|
|
107
|
+
1. **Generate Initial Heuristics**: LLMs are prompted to create heuristic functions as Python code
|
|
108
|
+
2. **Evaluate Heuristics**: Each heuristic is tested on validation data using heuristic-guided search
|
|
109
|
+
3. **Evolve Heuristics**: Iterative refinement through exploration (new ideas) and modification (tweaking existing)
|
|
110
|
+
4. **Select Best**: The best heuristic from all generations is chosen
|
|
111
|
+
5. **Test**: The selected heuristic is evaluated on test data
|
|
112
|
+
|
|
113
|
+
## Performance
|
|
114
|
+
|
|
115
|
+
Based on the research paper:
|
|
116
|
+
|
|
117
|
+
| Task | GPT-4o-mini | GPT-4o | Llama 3.1 70B | Best Baseline |
|
|
118
|
+
|------|-------------|--------|---------------|---------------|
|
|
119
|
+
| Blocksworld | 42.4% | **75.1%** | 59.1% | ~2× improvement |
|
|
120
|
+
| Game of 24 | 54% | **70%** | 69% | vs ToT 42/62/59 |
|
|
121
|
+
| Rubik's Cube (2×2) | **82.5%** | **83.1%** | **84.7%** | vs XoT 67/80/78 |
|
|
122
|
+
|
|
123
|
+
## Requirements
|
|
124
|
+
|
|
125
|
+
- Python 3.10+
|
|
126
|
+
- OpenAI API key (or other LLM provider)
|
|
127
|
+
- Optional: `litellm` for multi-provider support
|
|
128
|
+
|
|
129
|
+
## License
|
|
130
|
+
|
|
131
|
+
MIT License
|
|
132
|
+
|
|
133
|
+
## Citation
|
|
134
|
+
|
|
135
|
+
If you use AutoHD in your research, please cite:
|
|
136
|
+
|
|
137
|
+
```
|
|
138
|
+
@article{ling2025autohd,
|
|
139
|
+
title={Complex LLM Planning via Automated Heuristics Discovery},
|
|
140
|
+
author={Ling, Hongyi and Parashar, Shubham and Khurana, Sambhav and Olson, Blake and Basu, Anwesha and Sinha, Gaurangi and Tu, Zhengzhong and Caverlee, James and Ji, Shuiwang},
|
|
141
|
+
journal={arXiv preprint arXiv:2502.19295},
|
|
142
|
+
year={2025}
|
|
143
|
+
}
|
|
144
|
+
```
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"""AutoHD: Automated Heuristics Discovery for LLM Planning.
|
|
2
|
+
|
|
3
|
+
A Python package that enables LLMs to generate and evolve heuristic functions
|
|
4
|
+
for guiding inference-time search in complex planning tasks.
|
|
5
|
+
|
|
6
|
+
Based on the research paper: "Complex LLM Planning via Automated Heuristics Discovery"
|
|
7
|
+
(arXiv:2502.19295v1, Feb 2025, Texas A&M University).
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
__version__ = "0.1.0"
|
|
11
|
+
__author__ = "AutoHD Contributors"
|
|
12
|
+
__email__ = "contact@autohd.ai"
|
|
13
|
+
|
|
14
|
+
from autohd.core.autohd import AutoHD
|
|
15
|
+
from autohd.core.config import AutoHDConfig, LLMConfig, SearchConfig, EvolutionConfig
|
|
16
|
+
|
|
17
|
+
__all__ = [
|
|
18
|
+
"AutoHD",
|
|
19
|
+
"AutoHDConfig",
|
|
20
|
+
"LLMConfig",
|
|
21
|
+
"SearchConfig",
|
|
22
|
+
"EvolutionConfig",
|
|
23
|
+
"__version__",
|
|
24
|
+
]
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""Benchmark task implementations for AutoHD."""
|
|
2
|
+
|
|
3
|
+
from autohd.benchmarks.base import BenchmarkTask
|
|
4
|
+
from autohd.benchmarks.blocksworld import BlocksworldTask
|
|
5
|
+
from autohd.benchmarks.game24 import Game24Task
|
|
6
|
+
from autohd.benchmarks.rubiks_cube import RubiksCubeTask
|
|
7
|
+
|
|
8
|
+
__all__ = [
|
|
9
|
+
"BenchmarkTask",
|
|
10
|
+
"BlocksworldTask",
|
|
11
|
+
"Game24Task",
|
|
12
|
+
"RubiksCubeTask",
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def get_benchmark_task(task_name: str, **kwargs) -> BenchmarkTask:
|
|
17
|
+
"""Factory function to get a benchmark task by name.
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
task_name: Name of the task ('blocksworld', 'game24', 'rubiks_cube')
|
|
21
|
+
**kwargs: Arguments passed to the task constructor
|
|
22
|
+
|
|
23
|
+
Returns:
|
|
24
|
+
An instance of the appropriate BenchmarkTask subclass
|
|
25
|
+
|
|
26
|
+
Raises:
|
|
27
|
+
ValueError: If task_name is not recognized
|
|
28
|
+
"""
|
|
29
|
+
task_map = {
|
|
30
|
+
"blocksworld": BlocksworldTask,
|
|
31
|
+
"game24": Game24Task,
|
|
32
|
+
"rubiks_cube": RubiksCubeTask,
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if task_name not in task_map:
|
|
36
|
+
raise ValueError(
|
|
37
|
+
f"Unknown task '{task_name}'. "
|
|
38
|
+
f"Available tasks: {list(task_map.keys())}"
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
return task_map[task_name](task_name=task_name, **kwargs)
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"""Base class for benchmark tasks."""
|
|
2
|
+
|
|
3
|
+
import time
|
|
4
|
+
import logging
|
|
5
|
+
from abc import ABC, abstractmethod
|
|
6
|
+
from typing import List, Dict, Any, Callable, Optional
|
|
7
|
+
|
|
8
|
+
from autohd.core.config import SearchConfig
|
|
9
|
+
|
|
10
|
+
logger = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class BenchmarkTask(ABC):
|
|
14
|
+
"""Abstract base class for benchmark planning tasks.
|
|
15
|
+
|
|
16
|
+
All planning tasks (Blocksworld, Game of 24, Rubik's Cube) should inherit from
|
|
17
|
+
this class and implement the required methods.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
def __init__(
|
|
21
|
+
self,
|
|
22
|
+
task_name: str,
|
|
23
|
+
heuristic_func: Optional[Callable] = None,
|
|
24
|
+
validation_set: Optional[List[Any]] = None,
|
|
25
|
+
):
|
|
26
|
+
self.task_name = task_name
|
|
27
|
+
self.heuristic_func = heuristic_func
|
|
28
|
+
self.validation_set = validation_set or []
|
|
29
|
+
self.model = None # LLM model for action generation (set externally)
|
|
30
|
+
|
|
31
|
+
@abstractmethod
|
|
32
|
+
def state_representation(self) -> Any:
|
|
33
|
+
"""Return the state representation for this task."""
|
|
34
|
+
pass
|
|
35
|
+
|
|
36
|
+
@abstractmethod
|
|
37
|
+
def action_space(self, state: Any) -> List[str]:
|
|
38
|
+
"""Return the valid actions for a given state."""
|
|
39
|
+
pass
|
|
40
|
+
|
|
41
|
+
@abstractmethod
|
|
42
|
+
def transition(self, state: Any, action: str) -> Any:
|
|
43
|
+
"""Execute an action and transition to the next state."""
|
|
44
|
+
pass
|
|
45
|
+
|
|
46
|
+
@abstractmethod
|
|
47
|
+
def is_goal(self, state: Any) -> bool:
|
|
48
|
+
"""Check if a state is a goal state."""
|
|
49
|
+
pass
|
|
50
|
+
|
|
51
|
+
@abstractmethod
|
|
52
|
+
def heuristic(self, state: Any) -> float:
|
|
53
|
+
"""Evaluate the heuristic value of a state."""
|
|
54
|
+
pass
|
|
55
|
+
|
|
56
|
+
async def run(
|
|
57
|
+
self,
|
|
58
|
+
test_data: List[Any],
|
|
59
|
+
search_config: Optional[SearchConfig] = None,
|
|
60
|
+
model=None,
|
|
61
|
+
) -> Dict[str, Any]:
|
|
62
|
+
"""Run the benchmark on test data.
|
|
63
|
+
|
|
64
|
+
Args:
|
|
65
|
+
test_data: List of test cases/problem instances
|
|
66
|
+
search_config: Configuration for search algorithm
|
|
67
|
+
model: LLM model for action generation (if not set during initialization)
|
|
68
|
+
|
|
69
|
+
Returns:
|
|
70
|
+
Dictionary with accuracy, timing, and other metrics
|
|
71
|
+
"""
|
|
72
|
+
if model:
|
|
73
|
+
self.model = model
|
|
74
|
+
|
|
75
|
+
if search_config is None:
|
|
76
|
+
from autohd.core.config import SearchConfig
|
|
77
|
+
search_config = SearchConfig()
|
|
78
|
+
|
|
79
|
+
start_time = time.time()
|
|
80
|
+
successful = 0
|
|
81
|
+
total = len(test_data)
|
|
82
|
+
errors = []
|
|
83
|
+
|
|
84
|
+
for i, problem in enumerate(test_data):
|
|
85
|
+
try:
|
|
86
|
+
result = await self._solve_problem(problem, search_config)
|
|
87
|
+
if result.get("success", False):
|
|
88
|
+
successful += 1
|
|
89
|
+
except Exception as e:
|
|
90
|
+
errors.append({"problem_index": i, "error": str(e)})
|
|
91
|
+
logger.warning(f"Error solving problem {i}: {e}")
|
|
92
|
+
|
|
93
|
+
elapsed = time.time() - start_time
|
|
94
|
+
|
|
95
|
+
return {
|
|
96
|
+
"accuracy": successful / total if total > 0 else 0,
|
|
97
|
+
"successful": successful,
|
|
98
|
+
"total": total,
|
|
99
|
+
"errors": errors,
|
|
100
|
+
"error_rate": len(errors) / total if total > 0 else 0,
|
|
101
|
+
"time_seconds": elapsed,
|
|
102
|
+
"avg_time_per_problem": elapsed / total if total > 0 else 0,
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
async def _solve_problem(
|
|
106
|
+
self,
|
|
107
|
+
problem: Any,
|
|
108
|
+
search_config: SearchConfig,
|
|
109
|
+
) -> Dict[str, Any]:
|
|
110
|
+
"""Solve a single problem using heuristic-guided search.
|
|
111
|
+
|
|
112
|
+
Uses either Greedy BFS or A* based on configuration.
|
|
113
|
+
"""
|
|
114
|
+
from autohd.search import greedy_bfs, astar_search
|
|
115
|
+
|
|
116
|
+
if search_config.algorithm == "greedy_bfs":
|
|
117
|
+
result = await greedy_bfs.solve(
|
|
118
|
+
problem=problem,
|
|
119
|
+
heuristic_func=self.heuristic_func,
|
|
120
|
+
max_steps=search_config.max_steps,
|
|
121
|
+
timeout=search_config.timeout_seconds,
|
|
122
|
+
)
|
|
123
|
+
else: # astar
|
|
124
|
+
result = await astar_search.solve(
|
|
125
|
+
problem=problem,
|
|
126
|
+
heuristic_func=self.heuristic_func,
|
|
127
|
+
max_steps=search_config.max_steps,
|
|
128
|
+
timeout=search_config.timeout_seconds,
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
return result
|
|
132
|
+
|
|
133
|
+
def __repr__(self):
|
|
134
|
+
return f"{self.__class__.__name__}(task={self.task_name})"
|