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

# lua chat

> Send messages to the agent from the terminal against the sandbox or production, interactively or one message at a time

`lua chat` sends messages to your agent the way an end user would and streams the reply. In the sandbox it runs your locally compiled code; in production it runs the live versions, so production messages reach the same agent your end users talk to and are stored in its conversation history.

*Verified against lua-cli 3.33.0. The production log declaration described below is available from lua-cli 3.39.0.*

## Synopsis

```bash theme={null}
lua chat [-e <environment>] [-m <text>] [-t [<id>]] [--clear] [--agent-version <n>]
lua chat [-e <environment>] -b <text> <text>... [-d <ms>]
lua chat clear [--user <id|email|mobile>] [-t <id>] [--force]
```

## Description

`-e sandbox` and `-e production` choose the [environment](/concepts/environments); `staging` is accepted and means sandbox. Any other value exits 2 with `Invalid environment: "<value>". Must be "sandbox", "staging", or "production".` With `-m` or `-b` and no `-e`, the command defaults to sandbox and says so. With neither, it asks.

<Note>
  **`-e production` also decides which environment the turn is *logged* as.** A `lua chat` session reaches the platform over a development channel, and a development channel is recorded against the `sandbox` environment — so `-e production`, against the promoted agent, used to write log rows labelled `sandbox`. A [log drain](/drains/overview) scoped to `production`, or a `lua logs --environment production` filter, then saw nothing at all from that testing, which looks exactly like a broken drain.

  A `-e production` session now declares `environment: "production"` on the [chat request](/reference/rest/chat), its rows are labelled `production`, and a production-scoped drain receives them. **It may not be enabled on your deployment yet** — where it is not, `-e production` is recorded as `sandbox`, exactly as before. Three things hold either way:

  * **`-e sandbox` declares nothing.** A development channel already gives it the `sandbox` label it should have.
  * **`--agent-version <n>` declares nothing either**, even though a preview runs against production. It executes a snapshot that was never promoted, which is sandbox by every definition the platform uses.
  * **The declaration only ever raises.** A turn may declare `production` and never `sandbox`, so nothing a caller sends can move a real production turn out of a drain that selects it.

  Not every row of the turn follows. The chat rows themselves and the turn's tool, MCP, `rag`, skill, preprocessor, postprocessor and sandbox rows carry the declared environment; `runtime` rows, which the agent runtime writes from wherever it happens to log, stay `sandbox`. A drain selecting both environments sees the whole turn; one selecting `production` alone sees a real part of it, not all of it.
</Note>

Sandbox mode uses your locally compiled code and needs no `lua push`. The CLI compiles the project, registering any primitive the agent does not have yet, then uploads each skill's compiled tools and each preprocessor and postprocessor as a `<version>-sandbox` version of that primitive. Every message is then sent with overrides that point the agent at those sandbox versions and at the persona in your local `LuaAgent`. The code runs on the platform, not in your terminal; the live versions and end users are untouched. `lua chat -e sandbox` uploads your `.env` values with each sandbox version and sandbox turns read them; production turns read the server-side variables set with [`lua env production`](/reference/cli/env). Webhooks, jobs, triggers, and workflows take no part in a sandbox chat. Production mode sends messages with no overrides. `--ci` does not stop the environment question, which appears when you pass neither `-e` nor `-m`; pass `-e`.

Every chat belongs to a [thread](/concepts/execution-contexts). `-t <id>` scopes the conversation to that thread, `-t` with no value generates a fresh UUID and prints it, and omitting `-t` continues the default thread shared by all your earlier unscoped chats with this agent. For repeatable tests pass `-t`. `--clear` (alias `--clear-thread`) deletes history when the run ends: only that thread's with `-t`, otherwise all of your history with the agent. `--agent-version <n>` previews a staged or superseded [agent version](/reference/cli/version) in an isolated thread; it runs against production only and the version must exist.

`-b` sends several messages concurrently, each starting `-d` milliseconds after the previous one, and reports per message whether the agent responded, absorbed it into a batch, or errored. Each batched message is its own turn; for a scripted multi-turn conversation, call `lua chat -m` repeatedly with the same `-t`.

A message may attach files with `@<path>` tokens at the start or after whitespace: images, PDF and Office documents, and text files up to 10 MB each; tokens with unknown extensions stay in the text. After each turn the CLI counts the `agent_error` logs it produced and prints the [`lua logs`](/reference/cli/logs) command to inspect them; an empty reply prints debugging hints. `LUA_NO_HINTS=1` silences both. There is no `--json` output.

`lua chat clear` deletes conversation history for the configured agent: yours by default, one thread with `-t`, or another end user's with `--user`, which needs the `org:manage` permission. It asks for confirmation unless `--force` is passed.

## Arguments

| Argument | Values | Description |
| - | - | - |
| subcommand | `clear` | Optional; without it the command chats. |

## Options

| Option | Description | Default |
| - | - | - |
| `-e, --env <environment>` | `sandbox` or `production`; `staging` means sandbox. `production` also declares the turn's log rows as `production` — see [above](#description). | prompt, or sandbox with `-m`/`-b` |
| `-m, --message <text>` | Send one message, print the reply, exit. | interactive |
| `-b, --batch <text>...` | Send several messages concurrently. | — |
| `-d, --delay <ms>` | Stagger between batch messages. | `100` |
| `-t, --thread [id]` | Scope to a thread; no value generates a UUID. | default thread |
| `--clear` | Clear history when the run ends: the thread's with `-t`, else all of yours. | off |
| `--clear-thread` | Alias of `--clear`. | off |
| `--agent-version <n>` | Preview agent version `n` in an isolated production thread. | active version |

Options of `lua chat clear`:

| Option | Description | Default |
| - | - | - |
| `--user <identifier>` | Clear another end user's history by id, email, or mobile number. Needs `org:manage`. | your own history |
| `-t, --thread <id>` | Clear one thread instead of all history. | all history |
| `--force` | Skip the confirmation prompt. Required under `--ci`. | off |

## Examples

Test local code in the sandbox, in a fresh thread that is cleared afterwards. The compile and upload progress goes to stderr; the thread line, the reply, and the clear confirmation go to stdout:

```bash theme={null}
lua chat -e sandbox -m "What is the status of ticket TCK-1?" -t --clear --ci
```

```text Output theme={null}
💡 Sandbox mode: uses your locally compiled code — no lua push needed.
…
✅ Compiled 8 primitives (1 agent, 1 skill, 3 tools, 1 webhook, 1 preprocessor, 1 postprocessor) in 525ms
✅ Pushed 1 skills to sandbox
✅ Pushed 1 preprocessor(s) and 1 postprocessor(s) to sandbox
ℹ️  Thread: 9c6056a5-67d8-4e69-8fdf-09193bb3ff96

──────────────────────────────────────────────────
🌙 Response:
Thread: 9c6056a5-67d8-4e69-8fdf-09193bb3ff96
──────────────────────────────────────────────────

I couldn't find ticket **TCK-1**.
…
🧹 Chat history cleared for thread "9c6056a5-67d8-4e69-8fdf-09193bb3ff96".
```

Run the same scenario against production in a named thread from a script, then clear it:

```bash theme={null}
lua chat -e production -m "I need a refund for order 1042" -t refund-test --ci
lua chat clear -t refund-test --force --ci
```

Hold an interactive conversation with the sandbox and attach a screenshot:

```bash theme={null}
lua chat -e sandbox
```

Type `@./screenshot.png what does this error mean?` at the prompt; press Ctrl+C to exit.

Preview agent version 4 before promoting it:

```bash theme={null}
lua chat --agent-version 4 -m "Which tools can you use?"
```

Check how the agent batches rapid messages from one end user:

```bash theme={null}
lua chat -e sandbox -b "Hi" "Where is my order?" "Order 1042" -d 500
```

## Exit codes

| Code | Meaning |
| - | - |
| `0` | The reply was printed, or history was cleared. |
| `1` | `Agent version v<n> not found.`, `--agent-version` combined with `-e sandbox`, a sandbox upload failed, or the server returned an error for the message. |
| `2` | Invalid `-e` value, or not inside a project. |
| `9` | No credential, or the server rejected it. |
| `11` | The server or network is unavailable. |
| `12` | The model provider refused the request; the hint names the cause. Retrying unchanged fails the same way. |

## See also

* [Test an agent before you release](/ship/testing) — sandbox chat, threads, and `lua test` together
* [About environments](/concepts/environments)
* [`lua test`](/reference/cli/test) — run one tool with no model involved
* [`lua logs`](/reference/cli/logs) — read the errors a turn produced
* [`lua version`](/reference/cli/version) — what `--agent-version` previews
* [Ship logs to your stack](/drains/overview#agents-and-environments) — the drain a `-e production` turn can reach


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