Scaffold Configs¶
GalapagosConfig is a typed dataclass whose sections are named after the
six core components — population, selection_policy,
prompt_builder, proposer, evaluator, memory — plus top-level seed, run-level general, and
EvoX's meta co-evolution loop. The Evaluator implementation is supplied by the task; the
evaluator section is run-owned input for an evaluator that opts into receiving it. Section names
match the component role keys used in build_components and _ROLE_BASES exactly.
One shared GalapagosConfig spans all twelve scaffolds: each section dataclass holds the union of
every scaffold's fields, so a scaffold reads only the subset it needs. Per-scaffold defaults live
in the bundled src/galapagos/scaffolds/<name>/config.yaml (loaded by from_config(name)); the
dataclass carries the schema, types, and a generic fallback. Unknown sections/keys raise instead
of silently falling back.
import galapagos as gx
cfg = gx.GalapagosConfig.from_config("openevolve") # bundled defaults → typed config
cfg.population.num_islands # 5 (typed, IDE-checked)
cfg = gx.GalapagosConfig.from_config("openevolve", population__num_islands=8) # __ → .
cfg = gx.GalapagosConfig.from_config(path="my.yaml") # local YAML, validated on load
cfg.to_yaml("effective.yaml") # dump the effective config
The list below is grouped by component; under each, the keys each scaffold uses. Format is
config name: description (default value). A key whose value is routed to more than one component is
listed under its YAML section with [shared → ...]. Bundled YAMLs need only list the keys a scaffold
overrides — omitted keys take the dataclass default.
Run-level (orchestrator — not a component slot)¶
All scaffolds. Top-level seed feeds every SelectionPolicy's RNG; general is read by the base
scaffold.
seed: RNG seed, threaded into every SelectionPolicy (0; the openevolve preset sets 42 — OpenEvolve'srandom_seed)general.max_iterations: iteration budget (100; meta_harness defaults to 20 proposer rounds, with every candidate in a round evaluated before the counter advances; ale_agent uses 1000 to mirror the paper's reported approximate generation scale; algotune_agent uses 9999 as a safety cap and normally stops first at its upstream $1 model-spend limit)general.checkpoint_interval: write a checkpoint every N iterations whenrun_diris set (10)general.eval_mode: where the task'sevaluator.pyruns —docker(the task's own image) orlocal(a host subprocess) (docker). The only thing that decides it: the task card has no say, and no environment variable is read, so a run is reproducible from its config alone. There is no--eval-modeflag; set it like any other config value (--general.eval_mode local)general.language: candidate language override; otherwise inferred from the seed program (null)general.solution_file_suffix: suffix for candidate files handed to the Evaluator (.py)general.max_solution_length: reject candidates longer than this many characters (60000; the openevolve preset sets 10000 — OpenEvolve'smax_code_length; algotune_agent sets 1000000 because its multi-file workspace is packed into one Genome)general.mutation_approach: how the LLM mutates —diff_based_edit(SEARCH/REPLACE edits) orfull_rewrite(a whole new program), or any name registered with@register_mutation_approach(a custom MutationApproach). Resolved to an object that supplies the prompt instruction (add_prompt) and the response→codeparser; applies to everyLLMProposer-based scaffold. An unknown name is rejected at run start (diff_based_edit)
Inner retry (per-iteration resampling)¶
These general.* keys control how many times an iteration resamples the proposer (parent held fixed) on a no-diff / too-long / invalid result before moving on.
general.inner_retry_times: max propose+evaluate attempts per iteration; 1 = no retry, the original behaviour (1; the adaevolve, beam_search, best_of_n, best_of_n_attempts, evox, openevolve and topk presets set 3, SkyDiscover'sretry_times)general.inner_retry_feedback: inject the prior failed attempts (error + failed code/response + traceback, SkyDiscover-style) into each retry's prompt so the model avoids repeating them (true)general.inner_retry_solution_chars: cap on the failed solution/response shown in that feedback; set above max_solution_length so normal failures show in full, ceiling only guards pathological output (80000; the beam_search/evox presets set 1500, the SkyDiscover default)general.inner_retry_traceback_chars: cap on the (tail of the) traceback shown in that feedback (1000; the beam_search/evox presets set 800, the SkyDiscover default)
Recoverable proposal failures¶
IterationGuard is always active for model/proposer execution failures. A None proposal immediately
fails the current iteration; an empty/no-diff proposal follows general.inner_retry_times; and an
LLM exception becomes a failed iteration after the model client's own transient-request retries.
Failed iterations consume their budget slot and there is no consecutive-failure circuit breaker.
The guard intentionally does not catch selection, evaluator, population, setup, checkpoint, or
finalization exceptions, nor KeyboardInterrupt/SystemExit. Those failures mean the search state
or scoring contract may be unreliable, so the run remains fail-fast.
1. Population — the candidate store¶
adaevolve (AdaEvolveArchipelago)
population.num_islands: initial island count (2) [shared → SelectionPolicy]population.population_size: programs per island archive (20)population.k_neighbors: k for k-NN code-distance novelty (5)population.archive_elite_ratio: fraction protected from eviction (0.2)population.fitness_weight: elite-score fitness-percentile weight (1.0)population.novelty_weight: elite-score novelty-percentile weight (0.0)population.pareto_weight: folded into the elite score's fitness term —w_fit = fitness_weight + pareto_weight— so it is live, and raising it tilts the elite score toward fitness and away from novelty (0.4)population.migration_count: top programs sent to (k+1) mod K (5)
openevolve (MapElitesIslandsPopulation)
population.num_islands: island count (5) [shared → SelectionPolicy]population.archive_size: global elite-archive size (100)population.population_size: total population cap (1000)population.feature_dimensions: MAP-Elites axes ([complexity, diversity]) [shared → SelectionPolicy, PromptBuilder]population.feature_bins: bins per feature axis (10)population.migration_interval: migrate every N island generations (50)population.migration_rate: fraction of each island migrated to ring neighbours (0.1)population.diversity_reference_size: sample size for diversity computation (20)
evox (EvoXPopulation)
population.improvement_threshold: stagnation-reset gain τ (0.01)population.statistics_k: top-k scores in the φ descriptor (20)
topk (TopKPopulation) / best_of_n + best_of_n_attempts (BestOfNPopulation, keep-all, shared)
population.capacity: keep-all archive cap;null= uncapped (the default, matching SkyDiscover), an int bounds it (null)
beam_search (BeamPopulation)
population.beam_width: candidates kept in the beam (5)population.beam_diversity_weight: diversity-term weight, 0 = pure fitness (0.3) [shared → SelectionPolicy]population.beam_depth_penalty: exponential fitness penalty per search-tree depth, 0 = off (0.0)
meta_harness (MetaHarnessPopulation)
population.cost_metric: optional Pareto cost axis to minimize.nullkeeps scalarcombined_scoresearch; set a metric emitted by every valid evaluation to enable Pareto mode, or setgenome_charsexplicitly when source length is the intended cost (null)
2. SelectionPolicy — the active, stateful policy¶
adaevolve (AdaEvolvePolicy)
selection_policy.decay: EMA factor ρ for G, UCB rewards, decayed visits (0.9)selection_policy.intensity_min: exploration-probability floor (0.15)selection_policy.intensity_max: exploration-probability ceiling (0.5)selection_policy.fixed_intensity: intensity used when use_adaptive_search is false (0.4)selection_policy.use_adaptive_search: G-based intensity vs fixed (true)selection_policy.use_ucb_selection: UCB island routing vs round-robin (true)selection_policy.use_migration: ring migration on/off (true)selection_policy.use_dynamic_islands: spawn islands on global stagnation (true)selection_policy.migration_interval: migrate every N iterations (15)selection_policy.max_islands: island cap for dynamic spawning (5)selection_policy.spawn_productivity_threshold: spawn when improvements/evaluations < this (0.015)selection_policy.spawn_cooldown_iterations: min iterations between spawns (30)selection_policy.local_context_program_ratio: local share of inspirations (0.6)selection_policy.num_inspirations: inspirations per prompt (4)
openevolve (OpenEvolveSelectionPolicy)
selection_policy.exploration_ratio: P(uniform-random parent from current island) (0.2)selection_policy.exploitation_ratio: P(fitness-weighted parent from the archive) (0.7)selection_policy.elite_selection_ratio: top fraction of island used as inspirations (0.1)selection_policy.num_inspirations: top programs as inspirations (3) [shared → PromptBuilder as num_top_programs]selection_policy.num_diverse: diverse programs as inspirations (2) [shared → PromptBuilder]
evox (EvoXPolicy)
selection_policy.num_context_programs: inspirations from the active strategy's sample() each iteration (4)
topk (TopKPolicy)
selection_policy.num_inspirations: programs at ranks 2..K+1 used as context, K (4)
ale_agent (ALEAgentSelectionPolicy)
selection_policy.ale_children_per_parent: sibling branches generated from each best-first parent (30)selection_policy.ale_refinement_turns: evaluated implementation turns per branch before its best version returns to the frontier (3)
best_of_n (BestOfNPolicy)
selection_policy.best_of_n: reuse the same parent until N valid children have been produced from it, then commit to the global best and repeat; failed (parse/invalid) attempts are free retries that do not spend the budget (5)selection_policy.num_inspirations: context programs sampled from the top pool (4)
best_of_n_attempts (BestOfNAttemptsPolicy)
- reuses the same
selection_policy.best_of_n/selection_policy.num_inspirationskeys as best_of_n, but counts every attempt (valid or not), rotating the parent every N iterations on a fixed cadence
beam_search (BeamSelectionPolicy)
selection_policy.beam_selection_strategy: best | stochastic | round_robin | diversity_weighted (diversity_weighted)selection_policy.beam_temperature: softmax temperature for stochastic / diversity_weighted (1.0)selection_policy.num_inspirations: global top programs used as context (4)
3. PromptBuilder — the renderer¶
Most scaffolds' PromptBuilders take no config (fixed templates). openevolve
(OpenEvolvePromptBuilder) has no own keys — it reuses selection_policy.num_inspirations (as
num_top_programs), selection_policy.num_diverse, and population.feature_dimensions.
ale_agent (ALEAgentPromptBuilder)
prompt_builder.ale_domain_guidance: sample one of the four published algorithm-engineering strategy prompts for each sibling branch (true)prompt_builder.ale_include_history: add the rolling search-trajectory summary; false in the full Method 1&2 configuration to preserve sibling diversity (false)
meta_harness (MetaHarnessPromptBuilder)
prompt_builder.skill: serialized-view steering used byproposer.mode=llm, and the backward-compatible fallback whencoding_agent_skillisnull; accepts agalapagos.skillsid (e.g.meta_harness/text_classification), a path to a SKILL.md directory, ornoneto disable steering. The bundled default ismeta_harness/text_classification; the alternate ismeta_harness/terminal_bench_2.prompt_builder.coding_agent_skill: primary filesystem-native skill used bymode=coding_agent. The bundled default ismeta_harness/text_classification_filesystem; usemeta_harness/terminal_bench_2_filesystemfor the depth regime.nullfalls back toprompt_builder.skillfor custom/backward-compatible configurations.prompt_builder.top_k_sources: full sources of this many frontier members in the prompt (3)prompt_builder.reports_in_prompt: most recent ≤30-line candidate reports replayed (6)prompt_builder.trace_errors: execution-trace excerpts sampled errors-first (2)prompt_builder.trace_successes: then success excerpts sampled (1)prompt_builder.trace_max_chars: clip per trace excerpt (1500)prompt_builder.summary_max_rows: evolution-summary rows rendered into the prompt (200)- (also reuses
proposer.candidates_per_proposal)
4. Proposer — the variation operator¶
Every scaffold's proposer section can carry the shared model keys, consumed by build_model
when that scaffold or mode builds an API LLM (see Models): model selection
(model_name, model_path, api_key, api_base, optional models weighted-ensemble list),
generation (temperature 0.7, top_p 1.0, max_tokens 30000, reasoning_effort null), and
request handling (timeout 600, retries 3, retry_delay 5). API proposers can additionally set
Tavily tool controls (tool_call_on false, max_tool_rounds 3, max_tool_output_chars null, and
nested tavily_tool transport/search/filter/response options); see
Models — Tavily web search. Preset overrides: topk / best_of_n /
best_of_n_attempts set max_tokens 32000; openevolve sets top_p 0.95, max_tokens 4096,
timeout 60; algotune_agent sets temperature 0 and reasoning_effort high.
claude_code, codex, and Meta-Harness's default coding_agent mode use a CLI agent instead
of build_model; Meta-Harness uses these model fields only in proposer.mode=llm. Only
meta_harness adds a loop-shaping key.
meta_harness (MetaHarnessProposer)
proposer.mode: what the proposer is —coding_agent(a headless coding agent browses the on-disk archive D, reference-faithful) orllm(one API model call over a serialized view of D) (coding_agent)proposer.coding_agent: which headless agent whenmode=coding_agent—claude_code/codex/cursor_agent(claude_code)proposer.candidates_per_proposal: candidate programs emitted per proposal, k (3) [shared → SelectionPolicy, PromptBuilder]
claude_code (the scaffold shells out to the Claude Code CLI — no
GalapagosModel is built; general.max_iterations is the prompt-level turn budget)
proposer.claude_model: the CLI's--model(claude-*/sonnet/opus/haiku); null = CLI default (null)proposer.claude_cli_max_turns: the CLI's--max-turnssafety cap; null = 2×general.max_iterations(null)proposer.claude_wall_timeout_seconds: whole-session wall timeout; null = derived from the CLI cap/evaluator (null)proposer.reasoning_effort: the CLI's--effort(high)
The rest apply to a docker-mode task — the default — where the Claude Code session runs inside
the task's own container image. The Meta-Harness CLI also reuses these keys when its default
coding_agent=claude_code controller/proposer/evaluator loop is orchestrated in that container (a
local-mode run uses host processes instead):
proposer.claude_docker_image: null = the task's own image, resolved from its card (the Claude Code CLI is layered onto it on first use); set it to override the task image wholesale (null)proposer.claude_docker_cli_version: pin the installed CLI version (npm i -g @anthropic-ai/claude-code@X); null = latest (null)proposer.claude_docker_memory/claude_docker_cpus/claude_docker_network:docker runresource/network caps (null = unbounded / Docker's default)
codex (the scaffold shells out to one codex exec --json session; no GalapagosModel is
built, and general.max_iterations is the improvement budget written into TASK.md)
proposer.codex_model: the CLI's--model; provider prefixes are stripped (gpt-5.6-sol)proposer.codex_cli_max_steps: completed actionable JSONL-item safety cap; null = 2×general.max_iterations(null)proposer.codex_wall_timeout_seconds: whole-session wall timeout; null = derived from the action and evaluator caps (null)proposer.reasoning_effort: Codex reasoning effort (max; accepted values are model/CLI-version dependent)proposer.reasoning_summary:auto,concise,detailed,none, or null for the CLI default (auto)proposer.codex_web_search:disabled,cached,indexed, orlive(disabled)proposer.codex_docker_image: null = the task's image; set it to override the task image wholesale (null)proposer.codex_docker_cli_version: pin the installed@openai/codexversion; null = latest (null)proposer.codex_docker_memory/codex_docker_cpus/codex_docker_network:docker runresource/network caps (null = unbounded / the task or Docker default)
There is no verifier-topology knob for either single-agent scaffold: the agent and the framework's trusted scorer share a single
container — the scorer execs in, the agent is non-root, /eval is root-owned and unwritable. See
Task environments for how that image and its /workspace + /eval
layout are built.
Meta-Harness additionally requires a run directory (galapagos run ... --output-dir DIR, or
run_dir=... in Python), persists archive D under <run_dir>/meta_harness_D, and deliberately does
not support --resume / resume_from.
OpenEvolve's upstream
diff_based_evolutionandmax_code_lengthmap to run-level keys —general.mutation_approach(diff_based_edit|full_rewrite) andgeneral.max_solution_length(the openevolve preset sets 10000).allow_full_rewriteis not exposed: in diff mode theOpenEvolveProposerapplies whole-line SEARCH/REPLACE with no full-rewrite fallback — a response with no valid diff block is a no-op, as the reference discards it.
5. Evaluator — the task-owned scorer¶
The Evaluator source is supplied by the task, not the scaffold: task.evaluator runs the task's
evaluator.py inside the task's own container image via a ContainerEvaluator (the default), or in a
host subprocess via a SubprocessEvaluator. Both select the same evaluator source; dependencies,
hardware, isolation, and timing can differ.
The run-owned evaluator section carries optional LLM-judge request settings. Existing
evaluate(program_path) functions ignore it automatically. A task explicitly opts in with
evaluate(program_path, *, evaluator_config), which receives the effective section as a plain dict;
the same contract applies to evaluate_stageN and evaluate_final.
evaluator.model_name: user-facing judge model name (null)evaluator.model_path: provider model id; task code may fall back tomodel_name(null)evaluator.api_base: provider name or explicit API base URL (null)evaluator.api_key_env: name of the API-key environment variable to forward; secret values never enter the config (null)evaluator.temperature: judge sampling temperature (0.0)evaluator.top_p: nucleus-sampling cutoff (1.0)evaluator.max_tokens: maximum judge response tokens (4096)evaluator.reasoning_effort: provider-specific reasoning effort (null)evaluator.responses_api: optional Responses-vs-Chat API selection (null)evaluator.seed: provider-side sampling seed when supported (null)evaluator.timeout: per-LLM-request timeout, distinct from the task evaluator process timeout (120)evaluator.retries/evaluator.retry_delay: LLM request attempt count and delay (3 / 5.0)evaluator.request_params: provider-specific JSON parameters ({})
evaluator:
model_name: openai/gpt-5-mini
api_base: openrouter
api_key_env: OPENROUTER_API_KEY
temperature: 0.0
max_tokens: 2048
Where is a run-level choice and it lives in general.eval_mode (docker — the default — or local;
aliases container/sandbox and subprocess): set it like any other config value —
galapagos run --general.eval_mode local — or from code with GalapagosTask.set_eval_mode(). It is the only input — the card gets
no say, and neither does the environment — so a run is reproducible from its config alone.
6. Memory — the cross-cutting knowledge store¶
AdaEvolve and ALE-Agent tune Memory via config; the other scaffolds' Memory takes no keys.
adaevolve (AdaEvolveParadigmMemory)
memory.use_paradigm_breakthrough: paradigm-breakthrough on/off (true)memory.paradigm_window_size: binary global-improvement window (10)memory.paradigm_improvement_threshold: rate < this (full window, no active paradigm) → generate (0.12)memory.paradigm_max_uses: uses per paradigm before rotation (2)memory.paradigm_num_to_generate: ideas per generator call (3)memory.paradigm_max_tried: bounded history of tried paradigms (10)
ale_agent (ALEAgentMemory)
memory.ale_history_size: rolling branch/turn outcome summaries retained for Base and Method 1 prompts (12)
Meta loop — EvoX co-evolution (not one of the 6 component slots)¶
EvoX evolves its SelectionPolicy/Proposer as code. These meta.* keys are consumed by the
EvoXScaffold orchestrator (__init__/setup), not a single component.
meta.switch_interval: strategy-switch period W; null → auto = max(1, max_iterations × 0.10) (null)meta.meta_num_context_programs: strategy inspirations sampled from H per generation event (2)meta.meta_max_retries: meta-generation attempts per event, with failure feedback (3)meta.auto_generate_variation_operators: false → static DIVERGE/REFINE templates, no LLM (true)meta.use_llm_stats_insight: false → raw population-state text in the meta prompt (true)meta.use_problem_summary: problem-context summary guide call, cached per problem (true)meta.use_batch_summaries: batched [PROGRAM N] summaries of prior strategies (true)meta.max_strategy_chars: generated-strategy length cap (60000)