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

> Talk to a voice live from the browser, terminal, or a phone call; run voice tests; list compiled voices

`lua voice` starts a live [voice session](/concepts/voice) with one of the agent's voices, `lua voice test` runs the project's `*.voice.test.ts` files, and `lua voice list` prints the voices in the compiled output. Nothing here changes production; voice sessions use the sandbox.

*Verified against lua-cli 3.33.0.*

## Synopsis

```bash theme={null}
lua voice [--agent <name>] [--voice <name>] [--terminal | --phone <E.164>] [--caller-id <E.164>] [--context <json>] [--thread-id <id>]
lua voice test [--voice <name>] [--pattern <regex>] [--watch] [--bail] [--runner jest|vitest|auto]
lua voice list [--json]
```

## Description

`lua voice` picks an agent and a voice from the compiled manifest in `dist-v2/`, then a mode. `--agent` and `--voice` skip the pickers; `--voice` defaults to the primary voice, the first bound to the agent.

The mode is browser (a local page with microphone and speaker), terminal (`--terminal`, requires `sox`), or phone (`--phone`; the agent calls the number and the command exits once the call is dispatched). `--phone` and `--terminal` together are an error; both numbers must be E.164 (`+` and 6 to 15 digits). `--context` seeds the voice session with a JSON object; `--thread-id` sets the thread suffix its sandbox API calls are scoped to.

Without `--terminal` or `--phone` the command asks `How would you like to test?`. Under `--ci` that prompt, like the pickers, is refused and the command exits `1` with `✖ error: Interactive prompt required but --ci flag is set. Provide all required flags or arguments.`

`lua voice test` finds `*.voice.test.ts` files under the current directory (outside `node_modules` and build output) and runs them with `npx jest` or `npx vitest` with `LUA_VOICE_TEST=1` set. `--runner auto` picks Vitest if `package.json` depends on it, else Jest; with neither installed the command exits `1` with `✖ error: No supported test runner found.`. `--voice <name>` runs only `<name>.voice.test.ts`; `--pattern` overrides it. A failing run exits `1`.

`lua voice list` reads `dist-v2/manifest.json`; run [`lua compile`](/reference/cli/compile) first. It prints each voice's models, hooks, greeting, and owning agent, marking the primary voice `★`. `lua voice` needs a project directory and a credential; `list` needs only the compiled output; `test` needs neither.

## Arguments

| Argument   | Values         | Description                            |
| ---------- | -------------- | -------------------------------------- |
| subcommand | `test`, `list` | Omit it to start a live voice session. |

## Options

| Option                 | Description                                                                | Default                  |
| ---------------------- | -------------------------------------------------------------------------- | ------------------------ |
| `--agent <name>`       | Agent whose voice to use.                                                  | prompt if several        |
| `--voice <name>`       | Voice to use, or the test file to run for `test`.                          | primary voice; all files |
| `--terminal`           | Use the terminal microphone and speaker; requires `sox`.                   | off                      |
| `--phone <number>`     | Call this E.164 number.                                                    | —                        |
| `--caller-id <number>` | E.164 number to present; must be owned by the organization.                | —                        |
| `--context <json>`     | JSON object seeded into the voice session.                                 | —                        |
| `--thread-id <id>`     | Thread suffix for the voice session's sandbox API scope.                   | —                        |
| `--pattern <regex>`    | Test path pattern for `test`; overrides `--voice`.                         | `\.voice\.test\.`        |
| `--watch`              | Re-run `test` on file change.                                              | off                      |
| `--bail`               | Stop `test` on the first failure.                                          | off                      |
| `--runner <runner>`    | `jest`, `vitest`, or `auto`.                                               | `auto`                   |
| `--json`               | Machine-readable output for `list`.                                        | off                      |
| `--ci`                 | Global flag. Refuse any prompt with exit `1` instead of waiting for input. | off                      |

## Examples

List the voices in the compiled output.

```bash theme={null}
lua voice list
```

```text Output theme={null}
🎙️  1 voice:

★ field-line  (field-ops-voice (primary))
    llm: inference:openai/gpt-5.2-chat-latest
    stt: inference:deepgram/nova-3
    tts: inference:elevenlabs/eleven_v3
    hooks: —
    greeting: "Field ops line, how can I help?"
```

Get the same list as JSON for a script.

```bash theme={null}
lua voice list --json
```

```text Output theme={null}
[
  {
    "name": "field-line",
    "llm": "inference:openai/gpt-5.2-chat-latest",
    "stt": "inference:deepgram/nova-3",
    "tts": "inference:elevenlabs/eleven_v3",
    "greeting": "Field ops line, how can I help?",
    "hasOnEnter": false,
    "hasOnUserTurnCompleted": false,
    "hasOnExit": false,
    "hasTools": false,
    "agent": "field-ops-voice",
    "primary": true
  }
]
```

Have the agent call you, presenting a number the organization owns.

```bash theme={null}
lua voice --voice field-line --phone +15551234567 --caller-id +15557654321 --ci
```

Run one voice test file with Vitest and stop at the first failure.

```bash theme={null}
lua voice test --voice field-line --runner vitest --bail
```

## Exit codes

| Code | Meaning     | When                                                                                                                                   |
| ---- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `0`  | OK          | The voice session was dispatched, the tests passed, or the list printed.                                                               |
| `1`  | Error       | Unknown agent or voice, bad phone number or `--context`, no test runner, failing tests, no manifest, or a prompt refused under `--ci`. |
| `2`  | Usage       | Unknown subcommand or option.                                                                                                          |
| `9`  | Auth        | No valid credential for a live voice session.                                                                                          |
| `11` | Unavailable | Network error or a server 5xx while dispatching.                                                                                       |

The full table is in [Errors and exit codes](/reference/cli/errors-and-exit-codes).

## See also

* [`defineVoice`](/reference/sdk/voice) — voice definitions, models, hooks, and greeting
* [`Voice`](/reference/sdk/voice-runtime) — start calls from code
* [About voice](/concepts/voice)
* [Voice calls](/channels/voice-calls) — phone numbers and inbound calls
* [`lua logs`](/reference/cli/logs) — `--type calls` for recent calls
