Overview
What a climber exchanges: one subpackage each under src/hillclimb/modules/, each with its contract in a base.py.
What a climber exchanges, one subpackage each under src/hillclimb/modules/, each with its
contract in a base.py. Implementations import only hillclimb.sdk.
| module | what it decides | bundled | contract |
|---|---|---|---|
| Policies | what to try next | greedy, openevolve, gepa | modules/policies/base.py |
| Operators | how one attempt is made: the draft, debug, improve, ensemble scaffolds | draft, debug, improve, ensemble | modules/operators/base.py |
| Tuners | which parameter values to try | random, optuna | modules/tuners/base.py |
| Similarity | how alike two solutions are; drives the similarity map and reference views | solution-card, api-calls, code-tokens | modules/similarity/base.py |
| Memory | whether a search reads and writes the cross-search memory: the YAML under hillclimb/knowledge/ — cards, claims, credit, consolidation, papers, skills | files, none | modules/memory/ |
| Knowledge graph | how that memory is indexed and traversed: build folds the files into a graph, retrieve picks the claims a search is shown, query answers hillclimb knowledge query | knowledge-graph | modules/memory/base.py |
A climber is a directory with a climber.yaml naming a search policy (or a
whole loop), the operators it may use, their prompts and a tuner. Three are
bundled: greedy (debug failing tips, draft a few branches, improve the
best), openevolve (MAP-Elites over hillclimb's operators) and gepa
(reflective Pareto search, brings its own loop). A one-file climber is a
.py with one policy class. A search snapshots its climber, so editing the
live copy never changes a running search, and hillclimb climber check
replays recorded journals through an edited climber before an agent hour
is spent on it.
name: gepa
description: Reflective Pareto search; brings its own SearchLoop. Experimental.
loop: hillclimb.integrations.gepa.loop:GepaLoop
params:
max_metric_calls: 50
operators:
- hillclimb.integrations.gepa.operator:GepaReflectOperator
memory: files
tuner: random
holdout_timing: after # gepa's state never meets a holdout value, not even a failed hidden split