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

# Custom agents

> Run an ACP agent from a GitHub repository

Custom agents run over ACP from a source repository containing a `harbor-agent.json` manifest.
Connect the repository from your profile settings before using a private one.

The template below intentionally omits `source.ref`, so Harbor starts from the repository's default
branch and records the resolved commit SHA in the stored job config:

```json theme={"system"}
{
  "config": {
    "retry": {
      "exclude_exceptions": [
        "AgentTimeoutError",
        "VerifierTimeoutError",
        "RewardFileNotFoundError",
        "RewardFileEmptyError",
        "VerifierOutputParseError",
        "ApiUsageLimitError",
        "AgentSafetyRefusalError"
      ],
      "include_exceptions": []
    },
    "agents": [
      {
        "name": "acp",
        "source": {
          "path": ".",
          "repo": "<github-owner>/<custom-agent-repo>",
          "type": "github",
          "manifest": "harbor-agent.json"
        },
        "model_name": "<model-provider>/<model-name>",
        "secrets": ["<MODEL_API_KEY_ENV_VAR>"]
      }
    ],
    "datasets": [
      {
        "ref": "<dataset-ref>",
        "name": "<dataset-org>/<dataset-name>",
        "n_tasks": 3
      }
    ],
    "job_name": "<job-name>"
  },
  "job_secrets": {
    "<MODEL_API_KEY_ENV_VAR>": "<model-api-key>"
  },
  "dry_run": false
}
```

Replace every `<...>` value before submitting. To select an explicit revision, add
`"ref": "<branch-tag-or-commit>"` inside `source`.

The source rules are:

* `name` must be `acp` when `source` is present.
* `source.type` must be `github`, and `source.repo` must use `owner/repo` form.
* `source.ref` is optional and accepts a branch, tag, or commit SHA. When omitted, Harbor resolves
  GitHub `HEAD`, which is the repository's configured default branch and is normally `main`, then
  records the exact commit SHA in the stored config so retries stay reproducible.
* `source.path` defaults to `.` and selects the repository directory holding the agent project.
* `source.manifest` defaults to `harbor-agent.json` and is resolved relative to `source.path`.
* Custom agents bring their own model credentials. Supply the key in `job_secrets` or store it
  as a hosted secret, and name it in the agent's [`secrets`](/core-concepts/hosted-harbor/submitting-jobs#agent-secrets)
  either way. Select the credential matching `model_name`'s provider; it backs
  `HOSTED_INFERENCE_TOKEN` as described in [Inference Credentials](#inference-credentials).

The source directory needs a locked Python project and a manifest:

```json theme={"system"}
{
  "schema_version": 1,
  "id": "<agent-id>",
  "version": "<agent-version>",
  "protocol": "acp",
  "runtime": {
    "kind": "python-uv",
    "python": "3.12",
    "project": ".",
    "lockfile": "uv.lock",
    "entrypoint": ["python", "-m", "<agent-module>"]
  }
}
```

`schema_version` must be `1`, `protocol` must be `acp`, `runtime.kind` must be `python-uv`, and
`runtime.python` must be `"3.12"`. The entrypoint must be an executable that speaks ACP over standard
input and output, and its first element is a command name rather than a path. Commit the manifest,
the project files, and `uv.lock` to the repository.

To check repository access, the ref, and the manifest without launching anything, send the same
request with `"dry_run": true`. A successful validation returns the resolved repository, the pinned
commit, the manifest identity, and the access mode.

## Inference Credentials

Set `config.credential_mode` to choose how the custom agent receives its selected model credential:

| Mode               | `HOSTED_INFERENCE_TOKEN`                      | `HOSTED_INFERENCE_URL`           | How to connect                     |
| ------------------ | --------------------------------------------- | -------------------------------- | ---------------------------------- |
| `direct` (default) | The selected model provider's real credential | Not set                          | Use the provider's normal endpoint |
| `gateway`          | A scoped proxy credential                     | The hosted inference gateway URL | Use this URL with the scoped token |

Read `HOSTED_INFERENCE_TOKEN` for inference authentication. Only override the provider client's
base URL when `HOSTED_INFERENCE_URL` is set. An absent URL is expected in direct mode; do not
require it or substitute a hard-coded gateway URL.

Direct mode also injects selected secrets under their environment variable names, so agent code
can read their real values. Gateway mode proxies supported inference provider credentials; selected
non-provider secrets still arrive with their real values. See
[Agent Secrets](/core-concepts/hosted-harbor/submitting-jobs#agent-secrets) for supported providers and secret selection.
