> ## Documentation Index
> Fetch the complete documentation index at: https://docs.evolvingmachines.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Agents

> The built-in harnesses, how to configure an arm, and how to register your own agent.

An agent is a harness plus a model. `-a` names the harness, `-m` the model it drives. Seven harnesses are built in.

| Name on `-a` | Harness     |
| ------------ | ----------- |
| `claude`     | Claude Code |
| `codex`      | Codex       |
| `gemini`     | Gemini CLI  |
| `qwen`       | Qwen Code   |
| `kimi`       | Kimi Code   |
| `opencode`   | OpenCode    |
| `droid`      | Droid       |

```bash theme={"dark"}
evolve run \
  -d terminal-bench-4@4.0 \
  -a claude \
  -m fable \
  -l 5 \
  --watch
```

`-a <name[@version]>` can pin a harness version. Omitted, the latest is chosen once, when the job is created, so every trial installs the same version; it is recorded on every trial as `agent_info.version`. A pin that does not exist is refused with `agent_version_not_found`, and a pin on a registered agent is refused.

## Configure the arm

These flags apply to every arm of the job.

```bash theme={"dark"}
evolve run \
  -d terminal-bench-4@4.0 \
  -a codex \
  -m gpt-6-astra \
  -l 5 \
  --effort high \
  --preset no-internet \
  --ak config=./codex-settings.json
```

`--effort <value>` sets the reasoning effort; see [models](/core-concepts/models#reasoning-effort). `--preset <name>` applies a named settings bundle: `no-internet` turns the vendor's server-side web tools off, `pinned-context` fixes the context window at 200000 tokens. `--ak config=<path|inline JSON>` becomes the harness's native settings file inside the sandbox; your document is the base, the platform's routing sits on top, and a preset wins where they disagree.

Only `claude` and `codex` take a config or a preset; the [capability document](/sdk-reference/meta) publishes `supports_config` and `presets` per harness. An effort, preset or config a harness cannot honor is refused when the job is created, never silently skipped, and so is a config key that touches billing, base URLs, routing or environment.

Environment for the agent comes from two places, a task's own `[environment.env]` table and a secret attached with `--secret`; a job cannot add a third. See [secrets](/core-concepts/secrets) and [tasks](/core-concepts/tasks#environment-variables).

## Register your own agent

Any CLI can run as an agent. Register it once, and its name works on `-a` like a built-in.

```bash theme={"dark"}
evolve agent add acme-cli --install-script ./install.sh --run "acme-cli --headless"
evolve run \
  -d terminal-bench-4@4.0 \
  -a acme-cli \
  -m gpt-6-astra \
  -l 5 \
  --watch
```

`--install-script <path>` names a file; its contents are uploaded. `--dir <path>` uploads a local directory instead. `--run <command>` is required and runs with `sh -c`. `--ae KEY=VALUE` injects environment at run time and may repeat.

```bash theme={"dark"}
evolve agent list
evolve agent show acme-cli
evolve agent remove acme-cli
```

Removing an agent keeps the record of the past jobs that ran it. Registered agents are private, so another account's name reads as `agent_not_found`. The number you may hold is published as `agent_registration.max_per_user`; past it, `agent_limit_reached`.

The install script, or the uploaded directory, runs once with internet and no secrets: fetch only public sources and leave the executables in `$PREFIX/bin`. To change an agent without a gap, use `upsert` rather than remove and add.

### The run contract

Your `run_command` runs with `sh -c` at the task's working directory, and can rely on exactly this:

* The instruction arrives twice: on stdin, and at the path in `$EVOLVE_INSTRUCTION_FILE`.
* `$EVOLVE_GATEWAY_BASE_URL` is an OpenAI-compatible base URL that already ends in `/v1`, and `$EVOLVE_GATEWAY_API_KEY` is its credential. The same two values are also `$OPENAI_BASE_URL` and `$OPENAI_API_KEY`, so a CLI that reads its endpoint from the environment works unchanged.
* `$EVOLVE_MODEL` is the `model_name` of the arm.
* Your declared env may not override those six keys, and may not look like a credential; both are refused at registration with `agent_invalid_env`.

A CLI that routes through a config file must write that file inside `run_command`, from the contract values. `codex` is the worked example:

```bash theme={"dark"}
mkdir -p ~/.codex && cat > ~/.codex/config.toml <<EOF
model_provider = "evolve"
[model_providers.evolve]
name = "evolve"
base_url = "$EVOLVE_GATEWAY_BASE_URL"
env_key = "EVOLVE_GATEWAY_API_KEY"
wire_api = "responses"
EOF
codex login --with-api-key <<< "$EVOLVE_GATEWAY_API_KEY"
codex exec --skip-git-repo-check -
```

A CLI that ignores `OPENAI_BASE_URL` without this reaches for its vendor's endpoint, finds the box sealed, and spends the agent budget failing to connect. The spend cap is airtight only under `no-network`; see [models](/core-concepts/models).

Against a built-in, a registered agent has no live trace (there is no parser for an unknown CLI) and no `reasoning_effort` (put the flag in `run_command`); everything else is recorded the same way.

<Card title="agent reference" icon="terminal" href="/cli-reference/agent">
  Every flag of `evolve agent`.
</Card>
