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

# LuaAgent

> Agent configuration class with name, persona, model, model settings, and the primitive arrays the compiler bundles

`LuaAgent` is the object your project exports from `src/index.ts`: it names the [agent](/concepts/agents), holds its [persona](/concepts/persona) and [model](/concepts/models), and registers every primitive the compiler bundles. `lua compile` looks for `new LuaAgent({ … })` in `index.ts`, `src/index.ts`, `agent.ts`, `src/agent.ts`, `main.ts`, then `src/main.ts`, and compiles only the primitives referenced from that object's arrays. Pass the config as an object literal directly to the constructor; a config held in a variable isn't traversed, so its primitives aren't compiled.

*Verified against lua-cli 3.33.0.*

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

## Quick example

```ts src/index.ts theme={null}
import { LuaAgent } from 'lua-cli';
import ordersSkill from './skills/orders.skill';
import dailyDigest from './jobs/DailyDigestJob';
import orderPaid from './webhooks/OrderPaidWebhook';

export default new LuaAgent({
  name: 'shop-assistant',
  description: 'Answers order, delivery, and returns questions for Acme customers.',
  persona: 'You are the Acme support agent. Be concise and confirm order numbers before acting.',
  model: 'openai/gpt-5.4',
  modelSettings: { temperature: 0.2, reasoning: { effort: 'low' } },
  skills: [ordersSkill],
  jobs: [dailyDigest],
  webhooks: [orderPaid],
});
```

`lua push agent` uploads this configuration; the primitives in the arrays are pushed with their own `lua push <type>` commands or together with `lua push all`.

## Constructor

```ts theme={null}
new LuaAgent(config: LuaAgentConfig)
```

The constructor throws when:

* `persona` is an object with none of `base`, `voice`, `text`: `Agent persona object must have at least one of: base, voice, text`
* `modelSettings.temperature` is outside 0 to 2: `Agent modelSettings.temperature must be between 0 and 2`
* `modelSettings.topP` is outside 0 to 1: `Agent modelSettings.topP must be between 0 and 1`
* `modelSettings.maxOutputTokens` is less than 1: `Agent modelSettings.maxOutputTokens must be >= 1`
* `temperature`, `topP`, `topK`, `maxOutputTokens`, `presencePenalty`, `frequencyPenalty`, or `seed` is not a finite number: `Agent modelSettings.<key> must be a finite number`
* `modelSettings.stopSequences` is not an array of strings: `Agent modelSettings.stopSequences must be a string array`
* `modelSettings.reasoning` is not an object, its `effort` is not one of the six values, or its `show` is not a boolean: `Agent modelSettings.reasoning must be an object`, `Agent modelSettings.reasoning.effort must be one of: off, minimal, low, medium, high, max`, `Agent modelSettings.reasoning.show must be a boolean`

`name` and a string `persona` are not validated; `lua compile` warns `Agent should have a persona` when the persona is empty.

## Configuration

Fields of `LuaAgentConfig`, in declaration order.

<ParamField path="name" type="string" required>
  Agent name shown in the compiled manifest and in CLI output. The platform identifies the agent by the `agentId` in `lua.skill.yaml`, not by this name.
</ParamField>

<ParamField path="description" type="string">
  Summary of what the agent can do, read by a [Space](/concepts/spaces) when deciding whether to route a request to this agent. The persona owns tone and behavior. Omit it to leave any description set in the admin dashboard untouched; set `''` to clear it on the next `lua push agent`.
</ParamField>

<ParamField path="persona" type="PersonaText" required>
  The prompt text that defines who the agent is and how it behaves. A string, or `{ base?, voice?, text? }` where `base` is rendered on every channel, `voice` is appended in voice sessions, and `text` is appended on text channels. An object needs at least one key.
</ParamField>

<ParamField path="model" type="LuaAgentModel">
  A [model code](/concepts/models) such as `'openai/gpt-5.4'` (list them with `lua models list`), or a model resolver `(request: LuaRequest) => string | Promise<string>` that runs on every request with every runtime object available. Omit it to use the platform default model.

  ```ts theme={null}
  model: async (request) => (request.channel === 'whatsapp' ? 'openai/gpt-5.4-mini' : 'openai/gpt-5.4'),
  ```
</ParamField>

<ParamField path="modelSettings" type="AgentModelSettings">
  Sampling settings sent with every model call. A key left out keeps the provider's default. `reasoning` is the agent-level default; a per-request override wins.

  <Expandable title="keys">
    <ParamField path="temperature" type="number">
      0 to 2.
    </ParamField>

    <ParamField path="topP" type="number">
      0 to 1. Set either `temperature` or `topP`, not both.
    </ParamField>

    <ParamField path="topK" type="number">
      Top-K sampling. Provider support varies.
    </ParamField>

    <ParamField path="maxOutputTokens" type="number">
      At least 1.
    </ParamField>

    <ParamField path="presencePenalty" type="number">
      -2 to 2 where the provider supports it. The range is not checked at construction.
    </ParamField>

    <ParamField path="frequencyPenalty" type="number">
      -2 to 2 where the provider supports it. The range is not checked at construction.
    </ParamField>

    <ParamField path="stopSequences" type="string[]">
      Generation stops when the model emits one of them.
    </ParamField>

    <ParamField path="seed" type="number">
      Deterministic sampling where the provider supports it.
    </ParamField>

    <ParamField path="reasoning" type="{ effort?: 'off' | 'minimal' | 'low' | 'medium' | 'high' | 'max'; show?: boolean }">
      Default reasoning effort and whether the reasoning trace is returned. `show` defaults to `true`. An effort the resolved model doesn't support is mapped to its nearest tier.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField path="skills" type="LuaSkill[]" default="[]">
  [Skills](/reference/sdk/luaskill) and, through them, tools.
</ParamField>

<ParamField path="webhooks" type="LuaWebhook[]" default="[]">
  [Webhooks](/reference/sdk/luawebhook).
</ParamField>

<ParamField path="triggers" type="LuaTrigger[]" default="[]">
  [Triggers](/reference/sdk/luatrigger).
</ParamField>

<ParamField path="jobs" type="LuaJob[]" default="[]">
  [Jobs](/reference/sdk/luajob).
</ParamField>

<ParamField path="workflows" type="LuaWorkflow[]" default="[]">
  [Workflows](/reference/sdk/workflow-builder) built with `createWorkflow` or `defineWorkflow`. Tools referenced by a workflow's tool steps are compiled through this array too.
</ParamField>

<ParamField path="preProcessors" type="PreProcessor[]" default="[]">
  [Preprocessors](/reference/sdk/preprocessor), run before a message reaches the model.
</ParamField>

<ParamField path="postProcessors" type="PostProcessor[]" default="[]">
  [Postprocessors](/reference/sdk/postprocessor), run on the reply before it is sent.
</ParamField>

<ParamField path="mcpServers" type="LuaMCPServer[]" default="[]">
  [MCP servers](/reference/sdk/luamcpserver).
</ParamField>

<ParamField path="devices" type="LuaDevice[]" default="[]">
  [Devices](/reference/sdk/device-definition).
</ParamField>

<ParamField path="deviceTriggers" type="LuaDeviceTrigger[]" default="[]">
  Standalone [device triggers](/reference/sdk/device-definition).
</ParamField>

<ParamField path="voices" type="LuaVoice[]">
  [Voices](/reference/sdk/voice) the agent can answer with. A channel picks one in its channel configuration; without a binding the first entry is used.
</ParamField>

<ParamField path="batching" type="BatchingConfig">
  Message batching for this agent. A key left out falls back to the platform default.

  <Expandable title="keys">
    <ParamField path="firstMessageDelayMs" type="number">
      How long to hold the first message so rapid follow-ups join the same batch. `0` disables the hold.
    </ParamField>

    <ParamField path="debounceWindowMs" type="number">
      Window for collecting further messages while a turn is in flight. `0` disables batching.
    </ParamField>

    <ParamField path="maxBatchMessages" type="number">
      Maximum messages in one batch.
    </ParamField>

    <ParamField path="serializeProcessing" type="boolean" default="false">
      When `true`, a message arriving mid-turn waits for the current turn instead of aborting it. No effect when `debounceWindowMs` is `0`.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField path="governance" type="GovernanceConfig">
  [Governance](/concepts/governance) policy for tool calls, preprocessors, and postprocessors. The credential for `'api'` mode is read from the `GOVERNANCE_API_KEY` environment variable, never from this object.

  <Expandable title="keys">
    <ParamField path="mode" type="'sdk' | 'api'" required>
      `'sdk'` enforces `preset`, `injection`, and `rules` in the runtime; `'api'` defers to the server at `serverUrl`.
    </ParamField>

    <ParamField path="preset" type="'security'">
      Named baseline rule set, layered under `rules`.
    </ParamField>

    <ParamField path="injection" type="{ threshold: number; ml?: boolean; mlThreshold?: number }">
      Prompt-injection scan on inputs. `ml: true` adds the platform's classifier with its own `mlThreshold`.
    </ParamField>

    <ParamField path="rules" type="{ blockTools?: string[]; requireToolApproval?: string[]; tokenBudget?: number }">
      Tool names to block, tool names that need human approval, and a token budget. `requireApproval` is a deprecated spelling of `requireToolApproval`.
    </ParamField>

    <ParamField path="serverUrl" type="string">
      Enforcement server for `'api'` mode.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField path="browser" type="boolean | BrowserSwitchConfig">
  Browser tools for the agent, off by default. `true` turns them on with platform defaults; an object adds policy.

  <Expandable title="keys">
    <ParamField path="engine" type="'auto' | 'browser-use' | 'agent-browser'">
      `'auto'` lets the platform pick a local desktop browser or the cloud engine.
    </ParamField>

    <ParamField path="allowedDomains" type="string[]">
      Domains the browser may navigate to or request.
    </ParamField>

    <ParamField path="credentials" type="string[]">
      Names of vault credential entries the agent may use. Never raw secrets.
    </ParamField>

    <ParamField path="maxSessionMinutes" type="number">
      Hard cap on one browser session.
    </ParamField>
  </Expandable>
</ParamField>

## Methods

Read-only getters that return what was passed to the constructor.

| Method                                                                                                                                                         | Returns                                       |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- |
| `getName()`                                                                                                                                                    | `string`                                      |
| `getDescription()`                                                                                                                                             | `string \| undefined`                         |
| `getBrowser()`                                                                                                                                                 | `boolean \| BrowserSwitchConfig \| undefined` |
| `getPersona()`                                                                                                                                                 | `PersonaText`                                 |
| `getModel()`                                                                                                                                                   | `LuaAgentModel \| undefined`                  |
| `getModelSettings()`                                                                                                                                           | `AgentModelSettings \| undefined`             |
| `getSkills()`, `getWebhooks()`, `getTriggers()`, `getJobs()`, `getWorkflows()`, `getPreProcessors()`, `getPostProcessors()`, `getMCPServers()`, `getDevices()` | The registered array, `[]` when unset         |
| `getBatching()`                                                                                                                                                | `BatchingConfig \| undefined`                 |
| `getVoices()`                                                                                                                                                  | `LuaVoice[] \| undefined`                     |

There is no getter for `deviceTriggers` or `governance`.

## Types

`LuaAgentConfig`, `LuaAgentModel`, `PersonaText`, `AgentModelSettings`, and `LuaRequest` are exported types. `BatchingConfig`, `GovernanceConfig`, and `BrowserSwitchConfig` are declared inline; derive them from the config type.

```ts theme={null}
import type { LuaAgentConfig, LuaAgentModel, PersonaText, AgentModelSettings } from 'lua-cli';

type BatchingConfig = NonNullable<LuaAgentConfig['batching']>;
type GovernanceConfig = NonNullable<LuaAgentConfig['governance']>;
type BrowserSwitchConfig = Exclude<NonNullable<LuaAgentConfig['browser']>, boolean>;
```

## See also

* [About agents](/concepts/agents)
* [About persona](/concepts/persona)
* [About models](/concepts/models)
* [lua push](/reference/cli/push)
* [LuaSkill](/reference/sdk/luaskill)
