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

# LuaDecision

> A named, versioned decision declared on your agent and run by name

`LuaDecision` declares a decision once, on the agent, instead of repeating its questions at every call site. Each `lua push` stages a new version, and `lua version promote` makes it current. The dashboard can write a version too. `Decisions.run` always uses the current version, so you can sharpen a question or raise the confidence floor without touching the code that runs it, and go back to an earlier version if it gets worse.

*Verified against lua-cli 3.48.0.*

```ts theme={null}
import { LuaDecision, LuaAgent, Decisions } from 'lua-cli';
```

## Quick example

```ts theme={null}
import { Decisions, LuaAgent, LuaDecision } from 'lua-cli';

export const triage = new LuaDecision({
  name: 'triage',
  description: 'Route an inbound message to the right team',
  questions: {
    refund: Decisions.odds('Is the customer asking for a refund?'),
    team: Decisions.choice('Which team should handle this?', {
      billing: 'Charges, invoices, refunds',
      tech: 'Bugs, outages, login problems',
      sales: 'Upgrades, pricing questions',
    }),
  },
  provider: 'auto',
  minConfidence: 0.7,
});

export const agent = new LuaAgent({
  name: 'support',
  persona: 'You help customers with their orders.',
  skills: [supportSkill],
  decisions: [triage],
});
```

`defineDecision(config)` does the same as `new LuaDecision(config)`.

Anywhere in the agent's code:

```ts theme={null}
const r = await Decisions.run('triage', { message: input.text });
const { team, refund } = r.answers;
if (team.type === 'choice') team.choice;  // 'billing', typed as string
if (refund.type === 'odds') refund.odds;  // 0.93
```

Every answer can also be `{ type: 'refused' }`, so check `type` before you read its fields. `run` types `choice` as a string, not as the option labels, because the current version is read at run time.

## Configuration

<ParamField path="name" type="string" required>
  The name you run it by. Unique per agent. It must match `^[a-zA-Z0-9_-]{1,64}$`: 1 to 64 letters, digits, underscores or hyphens.
</ParamField>

<ParamField path="description" type="string">
  One sentence shown in the dashboard.
</ParamField>

<ParamField path="questions" type="Record<string, DecisionQuestion>" required>
  One to 64 questions built with `Decisions.odds`, `Decisions.choice` and `Decisions.score`.
</ParamField>

Every option of [`Decisions.ask`](/reference/sdk/decisions) is accepted too (`provider`, `model`, `fallback`, `region`, `zeroRetention`, `minConfidence`, `timeoutMs`, `cache`, `logState`) and becomes the version's default. A call can override any of them.

The constructor throws a `DecisionError` with code `decision_invalid` when the name breaks the rule above, when there are no questions, or when a question was not built with the builders or has empty instructions.

## Methods

### Decisions.run(name, state, options?)

```ts theme={null}
Decisions.run(name: string, state: DecisionState, options?: DecisionOptions & { images?: DecisionImage[] }): Promise<DecisionResult>
```

Runs the current version of the named decision against `state` and returns the same `DecisionResult` as `Decisions.ask`. `options` override the version's defaults for this call only. Every log row and usage row from `run` carries the decision's name and version.

A name the agent does not have throws a `DecisionError` with code `decision_not_found`. So does a decision you pushed but never made current, because its only version is still staged, and a deleted one.

## Versions

* `lua push` stages a new version of every declared decision, and `lua push decision` pushes decisions only. A staged version is not current, so `Decisions.run` keeps answering with the current one.
* A staged version goes live with `lua version create` then `lua version promote <version>`, with `lua decisions publish <name> <version>`, or with `lua push decision --auto-deploy`. Each one reaches running code at once.
* `lua version create` pins the newest version of each decision, whoever wrote it. If someone edits a decision in the dashboard after your last push, that edit is what the agent version pins and what promote ships.
* The dashboard's Decisions section edits the questions, options and confidence floor and saves them as a new version. Versions written there are marked as edited in the dashboard, and the next `lua push` writes a newer one from code.
* To roll back, run `lua decisions publish <name> <older version>` or promote an older agent version. Nothing is deleted.
* `lua decisions delete <name>` turns the decision off at once and keeps its versions. `Decisions.run` then throws `decision_not_found` for that name.
* `lua version status` shows a row for each decision, with the version in your project next to the one the live agent version pinned.
* `lua logs --type decisions` shows every run with the version that answered.

## The `lua decisions` command

`lua decisions` lists, tries and rolls back the decisions on the agent.

| Command | What it does |
| - | - |
| `lua decisions` or `lua decisions list` | Lists the decisions on the agent with their current version. |
| `lua decisions versions <name>` | Lists the versions of a decision newest first, with their source, questions and routing. |
| `lua decisions publish <name> <version>` | Makes that version current at once, and asks first unless you pass `--force`. |
| `lua decisions run <name> --message '<text>'` | Runs the current version on `{ message: <text> }` and prints each answer with the provider, rule, model, duration, tokens and any fallback. |
| `lua decisions delete <name>` | Turns the decision off and keeps its versions, and asks first unless you pass `--force`. |

`run` takes `--state '<json>'` in place of `--message`, and `--provider` and `--min-confidence` override the version for that run. `--json` prints machine-readable output for `list`, `versions` and `run`. In CI, `delete` needs `--force`.

Each action has aliases: `ls` and `view` for `list`, `history` and `list-versions` for `versions`, `rollback` and `deploy` for `publish`, `try` and `test` for `run`, and `rm`, `remove` and `del` for `delete`.

## Related

* [`Decisions`](/reference/sdk/decisions) for one-off questions and the question types.


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