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

# Quickstart

> Run your first agent inside a simulated environment

## Install

```bash theme={null}
npm i @burn0/silo
```

Silo runs entirely on your machine. There is no account, no API key, and nothing is sent anywhere.

<Warning>
  Always invoke the CLI as `npx @burn0/silo`. An unrelated package named `silo` exists on the public registry, so `npx silo` can fetch and run that instead.
</Warning>

## Create an environment

Scaffold a ready-made world to run against:

```bash theme={null}
npx @burn0/silo init demo --template crm
```

```
Created environment "demo" from CRM at ./.silo/environments/demo
```

This writes a complete environment into `.silo/environments/demo` — seeded data, a state type, 42 tools, tasks, and the verifiers that grade them. It is ordinary TypeScript and JSON in your repo; edit any of it.

<Tabs>
  <Tab title="CRM">
    `--template crm` — a staged sales pipeline: accounts, contacts, leads, opportunities and activity history. Good starting point, populated and small enough to read.
  </Tab>

  <Tab title="ERP">
    `--template erp` — a mid-sized industrial distributor with procure-to-pay, order-to-cash, inventory and budgeting. 185 tools across 18 tasks.
  </Tab>

  <Tab title="Blank">
    `--template blank` — the contract wired up and nothing in it. Use this when you are modelling your own domain.
  </Tab>
</Tabs>

See what it can be asked to do:

```bash theme={null}
npx @burn0/silo task list --env demo
```

```
TASK-001  easy    VER-001  Convert a qualified maritime lead
TASK-002  medium  VER-002  Rehome a departed rep's open pipeline
TASK-003  medium  VER-003  Book the Lumen point-of-sale win
TASK-004  easy    VER-004  Report the weighted value of open pipeline
TASK-005  medium  VER-005  Identify the rep with the most stalled deals
TASK-006  hard    VER-006  Find the weakest active rep against quota
```

## Write an agent

Silo does not give you an agent — it gives you a world and a boundary. Your agent is an ordinary file that Silo calls with the task, the available tools, and a `callTool` function.

Put it wherever you like:

<CodeGroup>
  ```typescript silo.agent.ts theme={null}
  type AgentInput = {
    task: string;
    tools: Array<{ name: string; description: string; inputSchema: Record<string, unknown> }>;
    callTool: (name: string, input: unknown) => Promise<{ output: unknown; isError?: boolean }>;
  };

  export default async function agent({ callTool }: AgentInput) {
    const forecast = await callTool("forecast_report", {});
    const { weightedAmount } = forecast.output as { weightedAmount: { amount: number } };

    return { output: `The weighted value of open pipeline is $${weightedAmount.amount}` };
  }
  ```

  ```javascript silo.agent.js theme={null}
  export default async function agent({ callTool }) {
    const forecast = await callTool("forecast_report", {});
    const { weightedAmount } = forecast.output;

    return { output: `The weighted value of open pipeline is $${weightedAmount.amount}` };
  }
  ```
</CodeGroup>

Both are plain ES modules, so your project needs `"type": "module"` in its `package.json`. Named `silo.agent.ts` in the directory you run from, it is picked up automatically; anywhere else, point at it with `--agent ./path/to/file.ts`.

This example is deliberately dumb. It calls one known tool and reports the number, so you can see a run end to end before wiring up a model.

<Card title="Bring Your Own Agent" icon="robot" href="/silo/agents/overview">
  The full contract, how tool errors come back, and where a real model loop plugs in.
</Card>

## Run it

```bash theme={null}
npx @burn0/silo run --env demo --task TASK-004
```

```
  Silo Run

  Task          TASK-004 — Report the weighted value of open pipeline
  Result        PASS
  Reward        1.00
  Duration      0.0s

  Tool calls    1
  Successful    1
  Errors        0

  Checks        3 / 3
  Required      1 / 1

  Run saved: .silo/runs/run_20260915012734_4t01
```

Every rollout starts from a fresh copy of the world, so runs cannot contaminate each other.

## Inspect the result

Each run leaves a directory behind:

```
.silo/runs/<runId>/
├── trace.jsonl       every event, append-only, in order
├── result.json       checks, reward, agent output, tool errors
├── state-diff.json   what the rollout changed
└── run.json          task, verifier, resolved config, timings
```

`result.json` shows how the answer was graded, and why:

```json result.json theme={null}
{
  "passed": true,
  "reward": 1,
  "requiredPassed": 1,
  "requiredTotal": 1,
  "toolCalls": 1,
  "toolErrors": 0,
  "terminationReason": "completed",
  "agentOutput": "The weighted value of open pipeline is $507500",
  "checks": [
    {
      "label": "The reported weighted total is correct",
      "passed": true,
      "detail": "answered 507500, expected 507500",
      "required": true
    },
    {
      "label": "The total is the figure the answer closes on",
      "passed": true,
      "detail": "final number = 507500",
      "required": false
    },
    {
      "label": "Answering left the world unchanged",
      "passed": true,
      "detail": "state is untouched",
      "required": false
    }
  ]
}
```

The expected figure is not written down anywhere. The verifier derives it from the seeded world, so editing an amount in `data/` changes the correct answer and the grading follows.

`trace.jsonl` is the record of what actually happened:

```
run_start
tool_call
tool_result
agent_output
run_end
verifier_result
```

When a run fails, read this first. It tells you whether the agent picked the wrong tool, sent bad arguments, or looped.

## Try a task that changes the world

`TASK-004` only asks a question. `TASK-002` asks for work:

```bash theme={null}
npx @burn0/silo run --env demo --task TASK-002
```

```
  Task          TASK-002 — Rehome a departed rep's open pipeline
  Result        FAIL
  Reward        0.60

  Checks        3 / 5
  Required      1 / 3

  Failed
  ✗ Every open deal of the departed rep moved to the new owner
  ✗ The departed rep owns no open deals
```

The agent above only reports a forecast, so it fails — and the reason is legible rather than a bare score. Note that it still scored `0.60`: some optional checks passed. A run passes only when every **required** check does.

`state-diff.json` confirms it:

```json state-diff.json theme={null}
{
  "scalars": [],
  "collections": {}
}
```

Nothing changed. An empty state diff alongside a failure is the signature of an agent that read but never wrote.
