# AgentSpec
URL: /docs/agent/api-reference/agent-spec

Every field of an agent spec — what runs, where, what it may do, and how it recovers.



## AgentSpec [#agentspec]

The JSON shape of an agent spec. `Alineo.start()` takes it as an object — read the file yourself (`await Bun.file(path).json()`) — and validates it with `validateAgentSpec()`. The same shape is the `spec` in every alineod request, and the JSON Schema at `https://registry.alineo.tech/spec/agent.json` that editors complete against.

```ts
import type { AgentSpec } from "alineo";
```

| Field                    | Type                                                 | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| ------------------------ | ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name`                   | `string`                                             | Unique identifier. Used as the sandbox session name.                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `harness`                | `"pi"`                                               | Agent-loop driver to run. Only `"pi"` is supported.                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `harnessVersion`         | `string?`                                            | npm version specifier for the Pi CLI (e.g. `"1.2.3"`, `"^1.2.0"`, or a dist-tag like `"latest"`). Passed to `npm install -g @earendil-works/pi-coding-agent@<harnessVersion>`. Omit to install whatever npm resolves as latest. Included in the setup-hash cache key, so changing it forces a fresh Pi CLI install.                                                                                                                                                             |
| `model`                  | `string`                                             | **Required.** Model ID passed to Pi via `--model`.                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `provider`               | `string?`                                            | AI provider passed via `--provider`. Omit for a direct Google API key.                                                                                                                                                                                                                                                                                                                                                                                                          |
| `packages`               | `string[]?`                                          | APT packages to install before Pi (e.g. `["python3", "git"]`).                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `env`                    | `Record<string, string \| CredentialEnvBinding>?`    | Env vars for the sandbox. Values may reference host env: `"${MY_VAR}"`. A value can also be a `CredentialEnvBinding` (`{ credential, host, injection, approval? }`) — that key never becomes a container env var; it's registered with the credential broker instead. `approval: "hold"` holds egress to `host` until approved. See [Credentials](/docs/core/concepts/credentials) and [Permission gate](/docs/agent/concepts/permissions#holding-network-egress-for-approval). |
| `resources`              | `{ cpu: string; memory: string; gpu? }?`             | Container resource limits. Falls back to `alineo.config.json` defaults.                                                                                                                                                                                                                                                                                                                                                                                                         |
| `setup`                  | `SetupStep[]?`                                       | Workspace setup steps — run after Pi install, baked into the snapshot.                                                                                                                                                                                                                                                                                                                                                                                                          |
| `permissions`            | `"auto" \| "ask" \| "readonly" \| PermissionPolicy?` | Human-in-the-loop tool-call gate. Omit (or `"auto"`) for the current behavior — no gate. See [Permission gate](/docs/agent/concepts/permissions).                                                                                                                                                                                                                                                                                                                               |
| `title`                  | `string?`                                            | Human-readable display name.                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `description`            | `string?`                                            | Short description of the agent.                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `author`                 | `string?`                                            | Author name.                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `categories`             | `string[]?`                                          | Arbitrary category tags.                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `metadata`               | `Record<string,string>?`                             | Not read anywhere in `alineo`; has no effect on the sandbox.                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `registryDependencies`   | `string[]?`                                          | Other agent spec URLs. Not read by `alineo` itself — used by `alineo add`, which fetches and saves each one first, depth-first.                                                                                                                                                                                                                                                                                                                                                 |
| `spawnDepth`             | `number?`                                            | Nesting-depth budget for `agent.spawn()`, force-decremented into each child's env. Non-negative integer. Required (directly or via `--depth`/`opts.spawnDepth`) for `agent.spawn()` to be allowed at all.                                                                                                                                                                                                                                                                       |
| `maxAgents`              | `number?`                                            | Optional cap on total descendants for this lineage, independent of `spawnDepth`. Non-negative integer. Unset means uncapped — unlike `spawnDepth`, omitting this doesn't disable spawning.                                                                                                                                                                                                                                                                                      |
| `teamId`                 | `string?`                                            | Team identity for the agent's memory scope (`@alineo-labs/memory`). Unset by default — most agents aren't tied to a team.                                                                                                                                                                                                                                                                                                                                                       |
| `resourceId`             | `string?`                                            | Resource identity for the agent's memory scope. Defaults to `name`. Kept separate from `name` because a spawned child's `name` is replaced with its forked sandbox's generated name; `resourceId` keeps the identity the spec declared.                                                                                                                                                                                                                                         |
| `onFailure`              | `"fail" \| "ask" \| "retry"?`                        | What alineod does when a turn fails. `"fail"` (default) ends the agent; `"ask"` holds it `blocked` for a decision; `"retry"` re-sends the prompt up to `maxRetries` times, then holds it. See [Supervision](/docs/alineod/concepts/supervision).                                                                                                                                                                                                                                |
| `maxRetries`             | `number?`                                            | Automatic re-prompts for `onFailure: "retry"`. No default — required for `"retry"` to retry at all.                                                                                                                                                                                                                                                                                                                                                                             |
| `maxConsecutiveFailures` | `number?`                                            | Circuit breaker: after this many failed turns in a row, alineod holds the agent `blocked` whatever `onFailure` says. Default `3`.                                                                                                                                                                                                                                                                                                                                               |
| `checkpoint`             | `boolean?`                                           | Take a [turn checkpoint](/docs/agent/concepts/reconnecting#turn-checkpoints) after every turn that finishes cleanly, so the agent can be restored if its container is gone. Off by default — it costs I/O on every turn. alineod takes them; see the linked page for the SDK alone.                                                                                                                                                                                             |

### Example [#example]

```json
{
  "$schema": "https://registry.alineo.tech/spec/agent.json",
  "name": "my-agent",
  "harness": "pi",
  "model": "gemini-flash-latest",
  "packages": ["python3", "git"],
  "env": { "GEMINI_API_KEY": "${GEMINI_API_KEY}" },
  "resources": { "cpu": "1000m", "memory": "2Gi" },
  "setup": [
    { "name": "Clone repo", "run": "git clone https://github.com/owner/repo /workspace" },
    { "name": "Install deps", "run": "npm ci", "cwd": "/workspace" }
  ]
}
```

***

## SetupStep [#setupstep]

A single workspace setup step.

```ts
import type { SetupStep } from "alineo";
```

| Field  | Type      | Required | Description                                                        |
| ------ | --------- | -------- | ------------------------------------------------------------------ |
| `name` | `string`  | yes      | Human-readable label, shown in logs and included in the setup hash |
| `run`  | `string`  | yes      | Bash command to execute                                            |
| `cwd`  | `string?` | no       | Working directory. Runs the command as `cd <cwd> && <run>`         |

See [Workspace setup](/docs/agent/concepts/workspace-setup) for details and examples.
