Metadata-Version: 2.5
Name: hillclimb
Version: 0.8.0
Summary: Hillclimbing on verifiable rewards: coding agents search for Python programs that optimize a score you define
Project-URL: Homepage, https://hillclimb.sh
Project-URL: Documentation, https://docs.hillclimb.sh
Project-URL: Repository, https://github.com/rebase-energy/hillclimb
Project-URL: Changelog, https://github.com/rebase-energy/hillclimb/blob/main/CHANGELOG.md
Project-URL: Issues, https://github.com/rebase-energy/hillclimb/issues
Project-URL: Discord, https://discord.gg/DDKh9UtSH
Author: Rebasian Technologies AB
License-Expression: MIT
License-File: LICENSE
Keywords: claude-code,codex,coding-agents,evolutionary-search,hillclimbing,optimization,program-search,verifiable-rewards
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Software Development :: Code Generators
Requires-Python: >=3.12
Requires-Dist: networkx>=3.0
Requires-Dist: pandas>=3.0.3
Requires-Dist: plotui>=0.6
Requires-Dist: psutil>=5.9; sys_platform == 'win32'
Requires-Dist: pydantic>=2.7
Requires-Dist: pydot>=4.0.1
Requires-Dist: pyyaml>=6.0
Requires-Dist: scikit-learn>=1.9.0
Requires-Dist: textual>=1.0
Requires-Dist: typer>=0.12
Requires-Dist: uv>=0.5
Provides-Extra: emflow
Requires-Dist: emflow<0.4,>=0.3.1; extra == 'emflow'
Provides-Extra: gepa
Requires-Dist: gepa<0.2,>=0.1.4; extra == 'gepa'
Requires-Dist: optuna<5,>=3.6; extra == 'gepa'
Provides-Extra: openevolve
Requires-Dist: openevolve<0.4,>=0.3; extra == 'openevolve'
Provides-Extra: optuna
Requires-Dist: optuna<5,>=3.6; extra == 'optuna'
Provides-Extra: tui
Description-Content-Type: text/markdown

<div align="center">

<picture>
  <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/rebase-energy/hillclimb/main/docs/assets/hillclimb-logo.svg">
  <img alt="hillclimb" src="https://raw.githubusercontent.com/rebase-energy/hillclimb/main/docs/assets/hillclimb-logo-light.svg" width="620">
</picture>

**Hillclimbing on verifiable rewards.**<br>
Use Claude Code and Codex to autonomously search for python programs that optimize a score you define.

<picture>
  <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/rebase-energy/hillclimb/main/docs/assets/hillclimb-mountain-dark.png">
  <img alt="An ASCII mountain: one climber on the summit under a gold star, another stuck on a lower peak" src="https://raw.githubusercontent.com/rebase-energy/hillclimb/main/docs/assets/hillclimb-mountain-light.png" width="560">
</picture>

[Website](https://hillclimb.sh?utm_medium=readme) ·
[Docs](https://docs.hillclimb.sh?utm_medium=readme) ·
[Quickstart](https://docs.hillclimb.sh/quickstart?utm_medium=readme) ·
[Python SDK](https://docs.hillclimb.sh/python?utm_medium=readme) ·
[CLI reference](https://docs.hillclimb.sh/cli?utm_medium=readme) ·
[Blog](https://docs.hillclimb.sh/blogposts?utm_medium=readme) ·
[Discord](https://hillclimb.sh/discord?utm_medium=readme)

[![PyPI](https://img.shields.io/pypi/v/hillclimb.svg)](https://pypi.org/project/hillclimb/)
[![Python 3.12+](https://img.shields.io/badge/python-3.12%2B-3776AB.svg?logo=python&logoColor=white)](https://pypi.org/project/hillclimb/)
[![Quickstart](https://github.com/rebase-energy/hillclimb/actions/workflows/quickstart.yml/badge.svg)](https://github.com/rebase-energy/hillclimb/actions/workflows/quickstart.yml)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/rebase-energy/hillclimb/blob/main/LICENSE)
[![Discord](https://img.shields.io/badge/discord-join%20chat-5865F2.svg?logo=discord&logoColor=white)](https://hillclimb.sh/discord?utm_medium=readme)

</div>

---

`hillclimb` provides a modular harness, tooling and testbed for exploring and
benchmarking autoresearch algorithms. The aim is to provide a tool to discover better
autoresearch methods, rather than build a single best autoresearcher.

You provide a verifier script, `verifier.sh`, and (optionally) a starting
solution, `solution.py`. `hillclimb` then spends a compute budget running a
search policy — a [climber](https://docs.hillclimb.sh/python/climber?utm_medium=readme) — that
decides which version to build on next and dispatches headless coding agents
to write, debug and improve it. Each version is scored through your verifier,
and `hillclimb` keeps the one that scores best.

The harness is fixed. The **climber** — what to try next and how each attempt
is prompted — is a block you can swap, edit and share, so two methods can be
compared on the same problem under the same budget.

## Quickstart

```bash
pip install hillclimb                      # or: uv tool install hillclimb
hillclimb connect claude                   # or codex, pi, openrouter; add --agent dummy to any run for no LLM at all

hillclimb init                             # hillclimb.yaml, problems/, runs/ in this folder
hillclimb problem get heilbronn-convex-13  # the verifier is the problem; description.md is the brief
hillclimb verify heilbronn-convex-13       # score the floor solution

hillclimb run heilbronn-convex-13 --budget 10m
hillclimb watch                            # live coding agents and scores (also: chart, tree)
hillclimb stop --all
hillclimb summit                           # copy the best solution.py into this folder
```

Every search also keeps its best in `runs/<run-id>/searches/<search-id>/best/`.
The [walkthrough](https://docs.hillclimb.sh/walkthrough?utm_medium=readme) goes through each step.

## Climbers

A climber is five modules, run in this order at every step of a search. Each
one is a built-in or a Python file you can edit.

| Module | Decides | Built in |
| --- | --- | --- |
| `selector_policy` | which candidate the next attempt builds on | `best`, `map-elites` |
| `operator_policy` | which operator to apply to it | `greedy` |
| `operators` | how one attempt is made: the prompt the coding agent gets | `draft`, `debug`, `improve`, `ensemble` |
| `tuner` | which parameter values to try on a candidate | `random`, `optuna` |
| `memory` | what carries over from one search to the next | `files`, `none` |

Together they are one block of config, in a run spec or as the folder's default
in `hillclimb.yaml`:

```yaml
climber:
  selector_policy: map-elites     # which candidate to build on next
  operator_policy: greedy         # which operator to use on it
  operators: [draft, debug, improve, crossover.py:Crossover]
  tuner: optuna
  memory: files
  params: {num_drafts: 5}
```

Every slot takes a prebuilt module, a `.py` file of your own, or
`package.module:Class`. Presets: `greedy`, `openevolve`, `gepa`. Or compose in
Python:

```python
from hillclimb import Budget, Climber, Problem
from hillclimb.policies import Greedy
from hillclimb.selectors import MapElites

problem = Problem("heilbronn-convex-13")
budget = Budget(wall_clock="10m", evaluations=40)
climber = Climber(selector_policy=MapElites(num_drafts=5), operator_policy=Greedy())

climber.search(problem, budget=budget)
climber.best, climber.history, climber.to_frame()
```

`MapElites` and the `openevolve` preset need `pip install 'hillclimb[openevolve]'`,
`tuner: optuna` needs `'hillclimb[optuna]'` and `gepa` needs `'hillclimb[gepa]'`.

`climber.start(...)` opens the same search to drive by hand, one `climber.step()` at a
time, and `Problem(name, score=my_function, ...)` defines a problem from a scoring function.
Runnable scripts are in [`examples/`](https://github.com/rebase-energy/hillclimb/tree/main/examples).

Compare two head to head:

```bash
hillclimb run heilbronn-convex-13 --climber greedy --climber openevolve   # one search each; --parallel-searches 3 runs three of each
hillclimb experiment report <run-id>
```

## Learn more

<table>
<tr>
<td width="50%" valign="top">

### [Walkthrough →](https://docs.hillclimb.sh/walkthrough?utm_medium=readme)

From first run to following and resuming a search.

</td>
<td width="50%" valign="top">

### [Problems →](https://docs.hillclimb.sh/problems?utm_medium=readme)

Define your own problem and write its verifier.

</td>
</tr>
<tr>
<td width="50%" valign="top">

### [Climbers →](https://docs.hillclimb.sh/climbers?utm_medium=readme)

The modules a climber is built from.

</td>
<td width="50%" valign="top">

### [Experiments →](https://docs.hillclimb.sh/experiments?utm_medium=readme)

Compare climbers on the same problem.

</td>
</tr>
<tr>
<td width="50%" valign="top">

### [Example problems →](https://docs.hillclimb.sh/examples?utm_medium=readme)

Every example problem and its best known value.

</td>
<td width="50%" valign="top">

### [CLI reference →](https://docs.hillclimb.sh/cli?utm_medium=readme)

Every `hillclimb` command and its flags.

</td>
</tr>
<tr>
<td width="50%" valign="top">

### [Python SDK →](https://docs.hillclimb.sh/python?utm_medium=readme)

Build and run searches from Python.

</td>
<td width="50%" valign="top">

### [Blogposts →](https://docs.hillclimb.sh/blogposts?utm_medium=readme)

Blog posts on hillclimbing.

</td>
</tr>
</table>

Questions, results, ideas: [join the Discord](https://hillclimb.sh/discord?utm_medium=readme).

## License

[MIT](https://github.com/rebase-energy/hillclimb/blob/main/LICENSE)
