# InferOptimal OpenEvolve tool

**Status:** Recommended for well-defined tasks with a reward that can be hill-climbed: a score you can compute for every candidate and want to raise.

Every harness measured side by side, on the same model: https://www.inferoptimal.com/tools/results

One of InferOptimal's swarm tools. A connected agent lists every agent tool, the subagent
tool included, with `list_agent_tools`.

Explicitly download, install, then run. Connecting an InferOptimal account or
endpoint never installs this tool. Requires Python 3.12+ and `make`; tested with
Python 3.12. Framework source and its direct dependencies are pinned in
`requirements.txt`; OpenEvolve commit is
`a1e9d91eecde612f0efc8e8e31f59b36998248c0`.

After these assets are published, install on the machine that owns the task files:

```sh
mkdir -p ~/.inferoptimal/openevolve
cd ~/.inferoptimal/openevolve
curl -fsSLO https://www.inferoptimal.com/swarm/inferoptimal_openevolve.py
curl -fsSLO https://www.inferoptimal.com/swarm/requirements.txt
curl -fsSLO https://www.inferoptimal.com/swarm/Makefile
curl -fsSLO https://www.inferoptimal.com/swarm/README.md
make install
```

From a source checkout, installation is `make -C swarm install`. The paired
environment is `swarm/.venv`, described by `swarm/requirements.txt`.

Use an existing InferOptimal inference endpoint and its key. This tool provisions
no hardware and creates no account. Put the endpoint key in a private text file
or the `INFEROPTIMAL_ENDPOINT_KEY` environment variable. Do not put it in a command
argument. An evaluator is local Python exposing `evaluate(program_path)` and
returning a metrics dictionary such as `{"combined_score": 0.8}`.

Every run needs an evaluator. Prefer a fixed, measurable one (tests, timings,
labelled data, a simulator). When the objective is a research question with
no fixed metric, such as a ruling to find across many documents, use the opt-in
[OpenResearch add-on](https://www.inferoptimal.com/openresearch/README.md): it
writes the seed brief and an `evaluator.py` for this tool, and its research
agents run through the InferOptimal subagent tool. This tool never installs or
starts it. Never let the proposing model grade its own candidates.

Launch one swarm:

```sh
~/.inferoptimal/openevolve/.venv/bin/python \
  ~/.inferoptimal/openevolve/inferoptimal_openevolve.py run \
  /absolute/path/initial_program.py /absolute/path/evaluator.py \
  --base-url https://YOUR-ENDPOINT.inferoptimal.com/v1 \
  --model YOUR-SERVED-MODEL \
  --key-file /absolute/private/path/endpoint-key.txt \
  --islands 2 --population-per-island 8 \
  --active-evaluations 4 --max-inflight 4 \
  --iterations 20 --temperature 1.0 --top-p 0.95 \
  --system-message-file /absolute/path/task.txt \
  --hardware-label YOUR-HARDWARE-IDENTITY \
  --output-dir /absolute/path/new-run-output
```

Defaults, each overridable:

- Plain OpenEvolve iterations: every request carries only the parent, its
  inspirations and evaluator feedback, with no conversation memory.
  `--agent-memory` (with `--agent-history full-resend|delta-append`) is opt-in.
  In measured runs, long agent conversations degraded on later turns while the
  same prompts sent statelessly stayed clean; `get_search_guidance` gives the
  measurement behind each offering's recommendation.
- SEARCH/REPLACE edits (`--diff-based`). `--full-rewrite` asks for whole programs
  instead, which costs about one program of output tokens per answer.
- Requests stream from the endpoint, so long generations are not cut by edge
  timeouts. `--max-tokens` defaults to 32768 and `--reasoning-effort` to `high`,
  sent as `chat_template_kwargs.reasoning_effort`. Which values a model accepts
  depends on its chat template; `get_search_guidance` gives the value measured
  for each offering.
- `--temperature` / `--top-p` are sent on every request when given; omitted,
  OpenEvolve's own values are sent. `get_search_guidance` gives each measured
  offering's recommended sampling.
- Prompt size: every prompt carries the parent plus `--num-top-programs`
  (OpenEvolve default 3) and `--num-diverse-programs` (default 2, the diverse
  programs and inspirations) whole programs, and up to `--max-artifact-bytes`
  (default 20480; 0 leaves them out) of evaluator output. With a large seed,
  `--num-top-programs 1 --num-diverse-programs 0` keeps prompts near one or two
  programs long.
- `--request-timeout` (default 1800 s) bounds one model request; `--eval-timeout`
  (default 300 s) bounds one evaluation. `--timeout` is a deprecated alias for both.
- `--system-message` or `--system-message-file` gives the task description to
  every iteration, so it need not live in the seed program's docstring.
- `--max-code-length` defaults to four times the initial program, at least 10000
  characters.
- `--max-inflight` is inference concurrency: simultaneous model requests, one per
  OpenEvolve worker. `--active-evaluations` is evaluator concurrency on this
  machine and is CPU-bound. They are independent: with more workers than
  evaluation slots, evaluations queue for a slot while requests keep flowing.
- `--usage-log` lines carry `looped`, `loop_reasoning`, `loop_content` and
  `search_replace` per generation. A reply counts as looped when a 2000-character
  window compresses below 5% with zlib or more than half the 4-word sequences in a
  200-word window repeat.

These numbers demonstrate syntax. They are not measured recommendations.
Islands hold evolving candidate programs. `population-per-island` sets the target
used to compute OpenEvolve's total population capacity; the framework's island
selection/migration rules determine actual membership. `active-evaluations` sets
OpenEvolve's process workers. `max-inflight` independently caps simultaneous model
requests across those processes. CPU evaluation may need fewer workers than the
endpoint's useful inference concurrency. A hardware label records caller input;
it does not establish a measured result.

The real framework uses OpenAI-compatible generation through a local loopback
proxy. The default remote protocol is chat completions. For a provider configured
for Responses, pass `--wire-api responses`; the proxy adapts the framework's chat
request to that same provider's `/responses` route and returns its final text to
OpenEvolve. It never switches endpoints, models or billing modes automatically.
Files, evaluators, candidate selection and checkpoints stay local;
prompts and generated candidates cross the existing remote inference API. The
loopback token is generated per run; the endpoint key is kept out of framework
configuration, run summaries and command output.

For every active generation, the tool uses existing `POST /box/v1/turn` events
`start`, `turn` and `end`, plus `POST /box/v1/beat` for long requests. After
registration, native `POST /v1/messages/count_tokens` counts the prompt before
inference. Prompt tokens plus the requested output budget must fit the manager's
`limit_tokens`; its separate compaction reserve is not available for generation.
The tool reports the counted prompt in a numeric `turn` and checks the returned
allocation again. Unsupported counting, invalid allocations and insufficient room
refuse generation explicitly; prompts are never silently truncated. This is
numeric cache admission. Without `--agent-memory` it keeps no conversations;
with it, compaction follows the manager's `compact` signal or the context cap. The box manager receives only
numeric usage and opaque session IDs.

The default manager address for a direct endpoint is its origin plus `/box`.
A managed `/optimized/v1` endpoint instead uses `/optimized/v1/box`. The managed
proxy accepts only authenticated `turn` and `beat` requests, namespaces session
IDs per managed session, and returns no global pool or other tenant's metadata.
Override the same-origin address with `--manager-base-url` if necessary.
If an endpoint does not expose a manager, inference continues and the run receipt
reports zero registrations. Optional registration is retried for each generation,
so a startup API bridge can hand off to an available GPU manager within one run.
No API conversation/cache is transferred by the tool. Add `--require-manager`
when manager participation is required; then inference is refused if registration
fails. Manager failure does not trigger hardware provisioning.

Stdout contains one JSON result. Logs go to stderr. The output directory contains
the best program, real OpenEvolve checkpoints/artifacts, and `inferoptimal-run.json`
with population settings, request counts, peak concurrency, counted admission
totals, provider-reported cached tokens (null when unavailable), and cleanup state.
Backend response counts use the managed endpoint's `X-InferOptimal-Backend`
header (`api-bridge`, `gpu`, or `unreported`); they do not infer a backend from
manager availability. Only a distinct managed-session count is retained, never
the session identifiers. The ordinary endpoint key/base remain the same across
a managed startup handoff. `--require-manager` refuses the API-only phase.
An inference failure never returns the endpoint's raw error text or key. Ctrl-C
requests framework shutdown and cache release; an in-flight HTTP request may take
up to `--request-timeout` seconds (default 1800) to finish. A release not confirmed by the
manager remains visible in the receipt and makes the run fail.

Resume a retained OpenEvolve checkpoint using `--checkpoint /path/to/checkpoint`
and a new `--output-dir`. Existing output directories are never overwritten.
Use the same task/evaluator/profile when comparing resumed or independent runs.

Official integration contracts:

- [OpenEvolve API](https://github.com/algorithmicsuperintelligence/openevolve/blob/a1e9d91eecde612f0efc8e8e31f59b36998248c0/openevolve/api.py)
- [Configuration](https://github.com/algorithmicsuperintelligence/openevolve/blob/a1e9d91eecde612f0efc8e8e31f59b36998248c0/openevolve/config.py)
- [OpenAI backend](https://github.com/algorithmicsuperintelligence/openevolve/blob/a1e9d91eecde612f0efc8e8e31f59b36998248c0/openevolve/llm/openai.py)
