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

# vetta session

> Create, send, stream, and manage sessions.

Manage [sessions](/docs/concepts/sessions) — directly-controlled runs of an agent.

## Commands

| Command                    | Description                                                                      |
| -------------------------- | -------------------------------------------------------------------------------- |
| `vetta session create`     | Start a session from an agent (optionally with a first `--message`).             |
| `vetta session send`       | Send a user message (`--message`; add `--interrupt` to steer a running session). |
| `vetta session stream`     | Stream events (resumable).                                                       |
| `vetta session run`        | Create + send + stream + wait for idle; exits on the terminal `stop_reason`.     |
| `vetta session get <id>`   | Retrieve a session.                                                              |
| `vetta session list`       | List sessions (paginated); `--stop-reason` narrows to one kind of stop.          |
| `vetta session inbox`      | Every session waiting on a person, and what each is waiting on.                  |
| `vetta session interrupt`  | Interrupt the current turn (session goes `idle`, `stop_reason: interrupted`).    |
| `vetta session confirm`    | Approve or deny a tool awaiting approval.                                        |
| `vetta session answer`     | Answer a question the agent parked the turn on.                                  |
| `vetta session usage <id>` | Show cumulative token usage and cost.                                            |
| `vetta session budget`     | Raise or remove the session cap.                                                 |
| `vetta session events`     | List events for a session.                                                       |
| `vetta session cancel`     | Cancel a running session.                                                        |

## create, send, stream

```bash theme={"system"}
SID=$(vetta session create --agent Refunder --window immediate --budget-usd 2.00 \
  --message "Refund order #4821" --output-schema ./refund.schema.json --json | jq -r .id)
vetta session send --session $SID --message "Actually, refund only 20.00 USD"
vetta session stream --session $SID --from-seq 0
```

`--from-seq` replays every event after a sequence number, so a reconnecting client never misses or duplicates events. Omit it to tail live from now. See [Events & streaming](/docs/concepts/events-and-streaming).

### A structured answer for one session

`--output-schema` takes a path to a JSON Schema file and overrides the agent's schema for this run;
`--require-output` refuses a clean ending that produced nothing matching it.

| Flag                     | Meaning                                                                                                                                                                                                                                       |
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--output-schema <path>` | JSON Schema the answer must match. Must be `"type": "object"` with at least one property — the schema *becomes* the tool the agent answers through, and a tool call's arguments are always an object, so anything else is refused with `400`. |
| `--require-output`       | Without a conforming answer the session goes idle with `stop_reason: error` instead of `end_turn`.                                                                                                                                            |

```bash theme={"system"}
vetta session run --agent Refunder --message "Refund order #4821" \
  --output-schema ./refund.schema.json --require-output --json | jq .structured_output
```

The document comes back on the session's `structured_output`, on the `session.idle` event and on the
`session.idle` webhook. See [Structured outputs](/docs/capabilities/structured-outputs).

<Note>
  **Money.** `--budget-usd` takes a decimal-dollar string and is converted client-side to integer micro-USD (the wire field is `cap_micro_usd`; `1 USD = 1_000_000` micro-USD). JSON amounts are integer `*_micro_usd`.
</Note>

## interrupt, steer & queue

A running session ignores a plain `send` (it returns `session_running`). Steer it in one call with `--interrupt`, interrupt on its own, or hold the words for the next turn with `--queue`:

```bash theme={"system"}
vetta session send --session $SID --interrupt --message "Stop — escalate to a human instead."
vetta session interrupt --session $SID     # no new message; stops at the next commit boundary
vetta session send --session $SID --queue --message "When you're done, also check the refund log."
```

`--queue` is `queue: true` on the wire: the message waits in the session's inbox and becomes the input of the turn that follows the one running; on an idle session it is a plain send. `--interrupt` and `--queue` together are refused (`validation_failed`).

## The inbox: what is waiting on you

A session that has stopped and is waiting on a person is `idle`, exactly like one that finished its
work — `status` cannot tell them apart. `stop_reason` can, so it is a filter:

```bash theme={"system"}
vetta session list --stop-reason awaiting_approval --human
vetta session list --stop-reason awaiting_answer --json | jq -r '.data[].id'
```

`vetta session inbox` asks that question for every reason a person can clear —
`awaiting_answer`, `awaiting_approval` and `budget_paused` — and prints the id, the `tool_call` to
quote back, and one line saying what each session wants:

```bash theme={"system"}
vetta session inbox --human
```

```
id                            agent_id                      stop_reason       tool_call  waiting_on
ses_01j…                      agt_01j…                      awaiting_answer   ask_01j…   Which mailbox should the crew send from?
ses_01k…                      agt_01j…                      awaiting_approval tc_9f…     bash
```

`awaiting_delegation` is deliberately absent: a coordinator waiting on its own threads is blocked on
work, not on you. `inbox` is a view over `list` and does not page — narrow it with `--stop-reason`
and `--limit`, or use `vetta session list` when there are more parked sessions than fit.

## confirm & tool-result

When the agent pauses on a guarded tool, the session goes `idle` with `stop_reason: awaiting_approval` and a `tool.confirm` event. Resolve it:

```bash theme={"system"}
vetta session confirm --session $SID --tool-call <id> --allow
vetta session confirm --session $SID --tool-call <id> --deny --reason "over policy limit"
```

Setting an agent up means approving the same tool several times with different arguments, one turn
apart each — the id being approved is derived from the call, so a second `identities_create` is a
second card. `--for-session` answers it once and grants that **tool** for the rest of the chat:

```bash theme={"system"}
vetta session confirm --session $SID --tool-call <id> --allow --for-session
```

It covers one tool name in one session and nothing else. It ends when the session does, is never
written onto the agent, and needs `--allow` — there is no session-wide deny. For a call through the
tool invoker (`tools_execute`) the tool granted is the one in its `tool` argument, not the invoker.

## answer a parked question

An agent that needs something from you parks the turn: the session goes `idle` with
`stop_reason: awaiting_answer` and carries the question in `pending_actions`. `confirm` cannot
resolve it — that route says only allow or deny, and "allow" is not an answer to "which mailbox?".

At a terminal, `vetta session answer` prints the question and asks for each field in turn:

```bash theme={"system"}
vetta session answer $SID
```

```
Which mailbox should the crew send from?
Mailbox
  e.g. hello@acme.com
> hello@acme.com
Tone
  1) formal
  2) warm
  or type anything else
> 2
```

A number picks an option; anything else is taken as typed, which is how you say the thing the agent
did not think of.

Under a script — or any redirected stdin — there is nobody to ask, so a prompt would hang forever.
Pass the whole answer instead, one flag per field; repeat a key to send several values:

```bash theme={"system"}
vetta session answer $SID --answer mailbox=hello@acme.com --answer tone=warm
vetta session answer $SID --tool-call ask_01j… --answer topics=pricing --answer topics=hiring
```

`--tool-call` is only needed when a session holds more than one parked question.

## run exit codes

`vetta session run` (and the top-level [`vetta run`](/docs/cli/overview#convenience-run)) block until the session goes idle/terminal, then set the process exit code from the terminal `stop_reason` so scripts and CI can branch. Idle is **not** inherently success — the exit code reflects `stop_reason`:

| `stop_reason`         | Exit code |
| --------------------- | --------- |
| `end_turn`            | `0`       |
| `error`               | `7`       |
| `awaiting_input`      | `3`       |
| `awaiting_approval`   | `4`       |
| `budget_paused`       | `5`       |
| `interrupted`         | `6`       |
| `max_iterations`      | `8`       |
| `context_exhausted`   | `9`       |
| `awaiting_delegation` | `10`      |
| `awaiting_answer`     | `11`      |

A session that never reported why it stopped exits `1`, and a bad command line exits `2`.

```bash theme={"system"}
vetta run --agent Refunder --message "Refund order #4821" || echo "stopped: exit $?"
```

## usage

```bash theme={"system"}
vetta session usage --session $SID --human
```

```json theme={"system"}
{
  "session_id": "ses_01H...",
  "consumed_micro_usd": 184200,
  "token_usage": { "input": 8120, "cache_write": 512, "cache_read": 4096, "output": 1340, "reasoning": 900 },
  "active_seconds": 37,
  "tool_calls": 4
}
```

## Changing tools mid-session

<Warning>
  **Not available.** There is no `vetta session update` command — a session's tool set is fixed at creation from the agent's configuration. To change it, update the agent (which creates a new version) and start a new session.
</Warning>

## budget

```bash theme={"system"}
vetta session budget --session $SID --usd 5.00    # raise; must exceed what is already consumed
```

| Flag        | Description                                    |
| ----------- | ---------------------------------------------- |
| `--session` | Session id (required).                         |
| `--usd`     | New cap as a decimal-dollar string (required). |

There is no `--remove`: a session always carries a cap. Raise it, or let the session stop at `budget_paused`.

## cancel

```bash theme={"system"}
vetta session cancel --session $SID
```

Stops a running session. It takes `--session` and no other flag.

<Warning>
  There is no `vetta session archive` and no `vetta session delete`. Unknown commands are a hard error, so either one exits `2` without touching the session.
</Warning>

<Note>
  Files a session produced in its sandbox are not durable unless the agent promoted them with `publish_file`. List what a run published with [`vetta file list --session $SID`](/docs/cli/files#what-a-run-produced) — there is no `vetta session files`.
</Note>
