> ## 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.

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

```typescript TypeScript theme={"system"}
const form = new FormData();
form.append("file", new Blob([bytes], { type: "text/csv" }), "orders.csv");
const file = await vetta.files.upload(form);
const list = await vetta.files.list();
const csv = await vetta.files.download(file.id);
```

## Getting inputs in front of an agent

Files travel **outward** by default. Uploading puts bytes in org storage; it does not put them in the agent's [computer](https://vetta.sh/docs/capabilities/computer.md), and a [session](https://vetta.sh/docs/concepts/sessions.md#create-a-session) takes no `files[]` — there is no create-time mount. What crosses the other way is the agent's own [`fetch_file`](https://vetta.sh/docs/capabilities/tools#reading-a-file-back-into-the-sandbox) call: upload the input, name its `fil_` id in the session's first `message`, and the agent writes it into its own workspace when it needs the bytes. For anything small, put the content in the first `message` itself; for anything on the open web, let the agent fetch it with [`web_fetch`](https://vetta.sh/docs/capabilities/tools#web-tools) or `bash`.

```bash CLI theme={"system"}
vetta session create --agent agt_01j8rh5ym2k7qv9xp3n6c4zwfd \
  --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](https://vetta.sh/docs/capabilities/computer.md) 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`](https://vetta.sh/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](https://vetta.sh/docs/concepts/sessions.md#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")
```

A published file may be up to **5 GiB** — a finished long-form render of a few hundred megabytes is
routine. Larger files are moved a slice at a time and are never held whole outside the sandbox, so
size costs transfer time and nothing else; a file still being written when it is published is
refused by name rather than stored truncated.

The tool takes a sandbox `path` and returns the new **published** file's id, name and size so the id can flow into a [structured output](https://vetta.sh/docs/capabilities/structured-outputs.md) or webhook. The file keeps the `session_id` as provenance but does not die with the session.

**path** `string` *required*

Absolute path of the artifact in the session sandbox, e.g. `/workspace/report.pdf`.

**name** `string`

The name to store it under in Files. Defaults to the basename of `path`.

**content\_type** `string`

MIME type; the library's `kind` (`image`, `video`, `audio`, `document`, `model`, `other`) is derived from it.

**title** `string`

A human title for the asset library.

**tags** `string[]`

Labels to find it by later with `find_files`.

**folder** `string`

The folder to put it in, such as a project name. Omitted, it lands in the folder of the last file the session filed.

### Name collisions

Names in Files are **not** unique keys — every publish creates a distinct file object with its own id, and a repeated `name` is stored as-is, so both remain listed. Key off the returned `id`, not the display `name`.

## Finding assets again

Everything in Files is also the organization's **asset library**: every file carries a `kind`, a `source` (who wrote it — an upload, a URL import, an image or video generation, a clip, a screenshot, a speech generation), optional `title`, `description` and `tags`, and an image's pixel dimensions. A generated picture or clip that was given no title or description reads with its prompt as its description and the prompt's first words as its title, so it is found by what it shows. An agent retrieves earlier assets with the built-in **`find_files`** tool:

```
find_files(query="hero", kind="image", tag="launch", limit=20)
find_files(folder="Episode 12")
```

Each file can sit in one [folder](https://vetta.sh/docs/api/files.md#folders). Every tool that writes a file takes the same optional `folder` argument.

It returns ids and metadata only — never bytes — so the agent can pass a `fil_` id on, or the same filters drive `vetta file list --kind --tag --search` and `client.files.list()`. Bring an asset in from the web with `vetta file import <url>` (the API fetches it server-side, so private and local addresses are refused), and describe any file after the fact with `vetta file update`. See [Files](https://vetta.sh/docs/api/files.md).

## Bringing an asset back into the sandbox

`find_files` stops at the id, and so does every generator — a [`generate_video`](https://vetta.sh/docs/capabilities/tools#generation-tools)
render is saved from the provider straight to storage and never lands on the computer's disk. The
built-in **`fetch_file`** tool is the inverse of `publish_file`: it writes files the organization
already holds into the session's sandbox, by id, so the agent can work on the bytes.

```
# from inside the agent's reasoning, it calls:
fetch_file(file_ids=["fil_seg1", "fil_seg2", "fil_seg3"], dir="segments")
```

This is the step that has to come first whenever a rendered asset is an *input* rather than a
deliverable — joining a 60–180s piece out of 30-second segments, overlaying a generated voiceover,
re-encoding for a platform that wants a different container. Pull the files down, do the work in the
shell, and `publish_file` the result as a new file. Up to eight ids a call and 5 GiB a file,
resolved against your organization's library and nobody else's; a session with no computer is
refused by name. See [Tools](https://vetta.sh/docs/capabilities/tools.md#reading-a-file-back-into-the-sandbox).

## Reading a session's outputs

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

> [!WARNING]
>
> Cancelling a session releases its sandbox, and the files it produced *in the sandbox* go with it. Files promoted with `publish_file` or uploaded through the Files API are organization-scoped and survive. Publish anything you need to keep before cancelling. See [Session operations](https://vetta.sh/docs/concepts/session-operations.md#archiving).

> [card] [Next: tools & plugins](https://vetta.sh/docs/capabilities/tools.md)
>
> The extension point every capability plugs into.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.