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

# Files

> Durable, organization-scoped storage for the artifacts a session produces.

**Files** is durable, organization-scoped storage: where inputs you upload and artifacts an agent chooses to keep live, independent of any single session's lifetime. Scratch work stays in the session sandbox; anything the agent should hand back goes to Files, where it persists until you delete it.

## Uploading inputs

Upload files up front for the agent to work against, then list or download them.

<CodeGroup>
  ```bash CLI theme={"system"}
  vetta file upload ./data/orders.csv --name orders.csv
  vetta file list
  vetta file download <file_id> > ./out/orders.csv
  ```

  ```typescript TypeScript theme={"system"}
  const file = await vetta.files.upload({ path: "./data/orders.csv", name: "orders.csv" });
  const list = await vetta.files.list();
  await vetta.files.download(file.id, "./out/orders.csv");
  ```
</CodeGroup>

## Getting inputs in front of an agent

Files travel **outward**. Uploading puts bytes in org storage; it does not put them in the agent's [computer](/docs/capabilities/computer), and a [session](/docs/concepts/sessions#create-a-session) takes no `files[]` — there is no create-time mount. To hand an agent an input today, put it in the session's first `message`, or let the agent fetch it itself with [`web_fetch`](/docs/capabilities/tools#web-tools) or `bash`.

```bash CLI theme={"system"}
vetta session create --agent Analyst \
  --message "Reconcile these orders against last month's ledger: $(cat ./data/orders.csv)"
```

The loop a session completes is therefore **agent works → `publish_file` → in Files, durably**.

## Two kinds of storage

| Where               | Scope                                                       | Lifetime                            |
| ------------------- | ----------------------------------------------------------- | ----------------------------------- |
| **Session sandbox** | The session's [computer](/docs/capabilities/computer) filesystem | Deleted when the session is deleted |
| **Files API**       | Your organization                                           | Persists until you delete it        |

Scratch work belongs in the sandbox. Anything the agent should hand back belongs in Files.

## Publishing an artifact

The built-in **`publish_file`** tool promotes a file from the session sandbox into the persistent Files store. It is not the only writer: what [`generate_image` or `generate_video`](/docs/capabilities/tools#generation-tools) produces also lands here, and the session is told the new `fil_` id. This is how a finished session leaves deliverables behind without a mandatory "deliver" step — the session simply goes [idle](/docs/concepts/sessions#lifecycle) and its published files remain.

```
# from inside the agent's reasoning, it calls:
publish_file(path="/workspace/report.pdf", name="Q3-refund-report.pdf")
```

The tool takes a sandbox `path` and returns the new persistent file object (`{ id, name, size, created_at }`) so the id can flow into a [structured output](/docs/capabilities/structured-outputs) or webhook:

<ParamField path="path" type="string" required>
  Absolute path of the artifact in the session sandbox, e.g. `/workspace/report.pdf`.
</ParamField>

<ParamField path="name" type="string">
  The name to store it under in Files. Defaults to the basename of `path`.
</ParamField>

<ParamField path="overwrite" type="boolean" default="false">
  How to handle a name that already exists in the org (see the collision rule below).
</ParamField>

### Name collisions

Names in Files are **not** unique keys — every publish creates a distinct file object with its own id. When `name` matches a file that already exists in the organization:

* `overwrite: false` (default) — the new file is stored under a **suffixed** name (`report.pdf` → `report-2.pdf`) so nothing is clobbered and both are retrievable.
* `overwrite: true` — the existing file's contents are **replaced in place**, keeping the same id so any prior reference still resolves.

Because ids are stable and unique, consumers should key off the returned `id`, not the display `name`.

## Reading a session's outputs

```bash CLI theme={"system"}
vetta file list --session $SID           # session-scoped + published
```

<Warning>
  Deleting a session permanently removes files it produced *in the sandbox*. Files promoted with `publish_file` or uploaded through the Files API are organization-scoped and survive. Download anything you need before deleting a session. See [Session operations](/docs/concepts/session-operations#deleting).
</Warning>

<Card title="Next: tools & plugins" icon="plug" href="/docs/capabilities/tools">
  The extension point every capability plugs into.
</Card>
