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

> ## Agent Instructions
> Unmute compiles to exactly three targets. Pipecat and LiveKit are code targets: compile writes a Python project you run. SLNG is a hosted target: compile writes a deployment body and SLNG runs the agent, so it has no `unmute dev`. Those three are the only values `provider` accepts in `targets.yaml`. Deepgram and ElevenLabs appear in these docs as model vendors, which is not the same thing as a target, and `slng` is both.
> The Go structs in `internal/spec` and `internal/ir` are the schema truth. Check a field against them, or run `unmute validate`, rather than against what you remember.

# Manifest

> Keep agents and coding assistants within your company's approved choices.

Use a manifest to keep new agents within your company's approved choices.

A manifest is a contract: it allows providers, models and other settings.
The agent package holds the prompts and tools that implement the use case.
**Save the rules, copy them into an agent, check the result.**

On this page:

* [Quickstart](#quickstart) - save a contract and create an agent
* [Save the company rules](#1-save-the-company-rules) - what a restriction means
* [Create an agent from them](#2-create-an-agent-from-them) - guided setup or a coding assistant
* [Check the package](#3-check-the-package) - validation and compilation
* [What an agent carries](#what-an-agent-carries) - the copied contract and its link
* [Example manifest](#example-manifest) - one complete contract
* [Every key](#every-key) - field reference
* [Advanced](#advanced) - saved defaults and later edits
* [Validation and limits](#validation-and-limits) - what checks can establish
* [Troubleshooting](#troubleshooting)
* [Where to go next](#where-to-go-next)

## Quickstart

These complete commands create a saved contract and a new agent package.
Both creation steps are interactive; finish and save each before continuing.

```sh Terminal — project folder theme={null}
unmute manifest create acme-corp
unmute init hotel-agent --manifest acme-corp
unmute validate hotel-agent
unmute compile hotel-agent
```

Choose the company's approved settings in the manifest editor.
Omitted rules add no restriction; a new manifest starts unrestricted.
The agent setup then offers choices within the saved contract.

For a coding assistant, use the [draft quickstart](/reference/cli/init#quickstart).
It creates an unfinished package without prompts and includes a brief you can
copy into your assistant.

## 1. Save the company rules

`acme-corp` is the local storage name. The editor separately lets you set the
company name and revision. The revision starts at `1` and changes only when
you edit it; it is not an Unmute or SDK version.

| Choice           | Meaning                                                                 |
| ---------------- | ----------------------------------------------------------------------- |
| No restriction   | Omit the rule and allow any otherwise-supported value                   |
| Selected values  | Allow only the listed values                                            |
| Allow nothing    | Explicitly allow no values; available for non-model rules in the editor |
| Allow all models | Permit every current and future model from one listed provider          |

A provider is the service the agent connects to. SLNG can serve models from
different makers. Keep provider `slng` for those models, even when their IDs
name Cartesia or Deepgram. Each role supports several providers and model IDs.

Choosing **Allow all models** omits that provider's `allow` field.
Providers missing from a restricted role remain forbidden. Permission does not
add target support or verify that an ID exists at the service.
See [Models](#models) for the field meanings.

Use arrows and Enter in menus, and Tab or Shift+Tab between form fields and
controls. F1 opens help; F2 switches sections. A form's Apply keeps the entry
in the draft. Only **Review and save** writes it to disk.
See [editor controls](/reference/cli/manifest) for the full workflow.

## 2. Create an agent from them

Use the same saved name when creating the package. These are alternatives;
choose one for a new directory.

| Who completes the package        | Command                                                |
| -------------------------------- | ------------------------------------------------------ |
| A person in guided setup         | `unmute init hotel-agent --manifest acme-corp`         |
| A coding assistant editing files | `unmute init hotel-agent --manifest acme-corp --draft` |

The draft selects no models, targets or channels. Install the
[Unmute skill](/reference/cli/skill), then give the assistant the use case and
ask it to complete the existing package under `hotel-agent/manifest`.
The CLI copies the contract; the assistant writes the agent.

The skill reads company rules before choosing bindings or tools. It uses exact
approved IDs when listed, preserves the contract, and explains conflicts
instead of weakening rules. Use the [complete assistant brief](/reference/cli/init#quickstart)
when handing it a draft.

## 3. Check the package

After guided setup or the coding assistant completes the package, run:

```sh Terminal — project folder theme={null}
unmute validate hotel-agent
unmute compile hotel-agent
```

Validation checks the package's own contract. Compilation also enforces it.
A draft fails these checks until its required settings are filled in.
Fix the agent's choices when they violate a rule; do not remove the rule to
make the check pass.

A successful compile is not a runtime test. Use the [browser loop](/dev/overview)
for LiveKit or Pipecat. SLNG runs on its hosted platform and has no `unmute dev`;
follow the [deployment workflow](/reference/cli/deploy).

## What an agent carries

Initialization copies the selected file to `hotel-agent/manifest`, preserving
its exact bytes. It also writes this link in `agent.yaml`.
If attaching a contract by hand, merge this single field into the existing
package; it is not a complete `agent.yaml`:

```yaml agent.yaml theme={null}
manifest: manifest
```

Commit both files. Validation and compilation work on another computer or in CI
without the saved library. Changing the library or its default never updates
an existing package automatically.

A root manifest requires its link. A link requires that file. Only the literal
link `manifest: manifest` is supported; no parent paths or remote URLs.
Packages with neither file nor link continue to work without a company contract.

## Example manifest

This is a complete contract file, not an agent package. Use it as a starting
point for company review; replace the example approvals with your own.

```yaml manifest theme={null}
manifest: acme-corp
version: 1

models:
  listen:
    - provider: slng
      allow:
        - deepgram/nova:3
  speak:
    - provider: slng
      allow:
        - deepgram/aura:2
  think:
    - provider: openai
      allow:
        - gpt-5.6-terra

languages:
  allow:
    - en

regions:
  models:
    - role: listen
      provider: slng
      allow:
        - eu-north
    - role: speak
      provider: slng
      allow:
        - eu-north
  deployments:
    - provider: livekit
      allow:
        - eu-central

targets:
  allow:
    - livekit

tools:
  kinds:
    allow:
      - builtin
  names:
    allow:
      - end_call
  builtin:
    allow:
      - end_call

tracing:
  allow:
    - langfuse
    - coval
```

## Every key

Only `manifest` and `version` are required. Add the rule blocks you need.
Omitting a rule adds no restriction. An explicit empty allowlist permits
nothing. Lists cannot contain `null`, blank strings or duplicate entries, and
unknown keys are refused.

### Identity

<ParamField path="manifest" type="string" required>
  The name of the organization this manifest describes, such as `acme-corp`.
  Any non-blank text is accepted. This is separate from the local name chosen
  with `unmute manifest create`, which identifies the saved file.
</ParamField>

<ParamField path="version" type="integer" required>
  The revision of this manifest: any integer greater than or equal to `1`.
  Increase it when you publish changed rules. It does not select the agent
  schema, an Unmute release, or a LiveKit or Pipecat SDK version.
</ParamField>

### Models

A **provider** is the service the agent connects to. A **model maker** creates
the model that service offers. For models served through SLNG, keep the
provider as `slng`, even when their IDs name Deepgram, Cartesia or Soniox.

Each role can allow several providers, and each provider can allow several
models. **Add provider** opens the service picker, then offers **Allow all models**
or **Add model ID**. Adding a model opens the input directly.
Use **Add model ID** again for more models, or **Add provider** for another service. Completed entries stay in your draft as you move between
screens; no extra Apply step is needed.

The guided editor does not offer **Allow nothing** for models.
Existing empty model rules remain visible and must be repaired before saving.
Add models, choose **Allow all models** for a provider, or choose **No restriction** for the role.
The YAML format and `--editor` still support explicitly empty lists.

<ParamField path="models" type="object">
  Restricts model choices by role. Its only keys are `listen`, `speak` and
  `think`. Each role contains a list of provider entries. Agents still define
  their own model profiles; the manifest approves exact provider/model pairs.
  Turn models are outside these rules.
</ParamField>

<ParamField path="models.listen" type="object[]">
  Allowed speech-to-text (STT) providers and models. Omit it for no STT
  restriction, or write `listen: []` to allow no STT models. When present,
  providers missing from this list are forbidden for this role. A provider
  may appear only once.
</ParamField>

<ParamField path="models.listen[].provider" type="string" required>
  The exact provider value used by the agent's listen profile, such as `slng`
  or `deepgram`. See [STT providers](/models/stt) for supported integrations
  on each target. Provider names are strings, not a fixed manifest enum.
</ParamField>

<ParamField path="models.listen[].allow" type="string[]">
  Omit this field to allow all current and future models from this provider.
  Other providers remain forbidden unless listed for the role.
  Exact model IDs approved for this provider, such as `deepgram/nova:3` with
  `slng`. Model IDs are provider-defined strings. No wildcards or prefix
  matching; case must match. An empty list approves none of this provider's
  STT models. There is no default model.
</ParamField>

<ParamField path="models.speak" type="object[]">
  Allowed text-to-speech (TTS) providers and models. Omit it for no TTS
  restriction, or write `speak: []` to allow no TTS models. Providers not
  listed are forbidden for this role. A provider may appear only once.
</ParamField>

<ParamField path="models.speak[].provider" type="string" required>
  The exact provider value used by the agent's speak profile, such as `slng`
  or `elevenlabs`. See [TTS providers](/models/tts) for target support.
  Provider names are strings, not a fixed manifest enum.
</ParamField>

<ParamField path="models.speak[].allow" type="string[]">
  Omit this field to allow all current and future models from this provider.
  Other providers remain forbidden unless listed for the role.
  Exact model IDs approved for this provider, such as `deepgram/aura:2` with
  `slng`. IDs are provider-defined and case-sensitive; wildcards are not
  supported. An empty list approves no models. This does not restrict voice
  IDs or supply a default voice.
</ParamField>

<ParamField path="models.think" type="object[]">
  Allowed language-model (LLM) providers and models. Omit it for no LLM
  restriction, or write `think: []` to allow no LLM models. Providers not
  listed are forbidden for this role. A provider may appear only once.
</ParamField>

<ParamField path="models.think[].provider" type="string" required>
  The exact provider value used by the agent's think profile, such as
  `openai` or `slng`. See [LLM providers](/models/llm) for target support.
  Match the configured provider, including when it routes to another service.
  Provider names are strings, not a fixed manifest enum.
</ParamField>

<ParamField path="models.think[].allow" type="string[]">
  Omit this field to allow all current and future models from this provider.
  Other providers remain forbidden unless listed for the role.
  Exact model IDs approved for this provider, such as `gpt-5.6-terra` with
  `openai`. IDs are provider-defined and case-sensitive. No wildcards or automatic model choice. An empty list approves
  no models.
</ParamField>

### Languages

<ParamField path="languages" type="object">
  Limits configured STT and TTS languages. Its only key is `allow`. Omitting
  this block adds no language restriction. It changes no LLM prompt and
  does not guarantee the language of every spoken word.
</ParamField>

<ParamField path="languages.allow" type="string[]" required>
  Language tags such as `en`, `es` or `en-US`. Values are not a fixed enum:
  the accepted shape is 2 to 8 letters, followed by zero or more hyphen-separated
  groups of 1 to 8 letters or digits. The speech integration must also support
  the configured tag.

  Matching ignores case, but uses the whole tag: `en` does not approve
  `en-US`. No language is chosen by omission. An empty list forbids all
  speech languages, including an unset one. For a nonempty list, automatic
  or hidden language settings that cannot be checked produce a warning.
</ParamField>

### Regions

<ParamField path="regions" type="object">
  Limits model-service and deployment regions separately. Its only keys are
  `models` and `deployments`. Neither list sets the other location.
</ParamField>

<ParamField path="regions.models" type="object[]">
  Region rules for model services, matched by `role` and `provider`. Each
  pair may appear only once. An omitted or empty rule list adds no model
  region restrictions; a rule's own empty `allow` list forbids that pair.
  Providers and roles with no matching row have no added region rule.
</ParamField>

<ParamField path="regions.models[].role" type="listen | speak | think" required>
  Exactly one of `listen` (STT), `speak` (TTS), or `think` (LLM).
  There is no default and no `turn` option.
</ParamField>

<ParamField path="regions.models[].provider" type="string" required>
  The exact configured model provider this row governs, such as `slng`
  or `aws`. This is a model provider, not the deployment target. It must be
  nonempty; provider names are not a fixed manifest enum.
</ParamField>

<ParamField path="regions.models[].allow" type="string[]" required>
  Exact native region names for the matched service. There are no shared
  `EU` aliases, wildcards or automatic geographic conversions. Matching is
  case-sensitive. An empty list forbids this provider/role even when its
  region is unknown. A nonempty list warns when the region cannot be checked.

  The compiler currently reads these settings:

  | Service                                 | Agent setting       | Region values                                                                                     |
  | --------------------------------------- | ------------------- | ------------------------------------------------------------------------------------------------- |
  | SLNG listen/speak/think on code targets | `params.world_part` | `us-east`, `us-west`, `br`, `eu-west`, `eu-north`, `gb`, `za`, `il`, `jp`, `sg`, `id`, `in`, `au` |
  | AWS think on LiveKit                    | `params.region`     | Native AWS region strings; there is no closed list in Unmute                                      |

  Other providers, unsupported settings and endpoints supplied through
  environment variables do not establish a verifiable model region.
  A checked gateway setting is not proof of the upstream processing location.
</ParamField>

<ParamField path="regions.deployments" type="object[]">
  Region rules matched by deployment provider. Each provider may appear only
  once. Omitting this list or a provider's row adds no region restriction
  for that provider.
</ParamField>

<ParamField path="regions.deployments[].provider" type="livekit | pipecat | slng" required>
  Exactly one of `livekit`, `pipecat`, or `slng`. Match the target's
  `provider`, not its instance name. There is no default.
</ParamField>

<ParamField path="regions.deployments[].allow" type="string[]" required>
  Exact native values permitted in the target's `deployment_region`.
  If the target declares several regions, every region must be allowed.
  An empty list forbids deployment on this provider, including when no
  region is declared. With a nonempty list, an omitted region warns.

  LiveKit and Pipecat use their platform's region strings; Unmute does not
  maintain a closed list. SLNG uses the same 13 regions as its model services:
  `us-east`, `us-west`, `br`, `eu-west`, `eu-north`, `gb`, `za`, `il`, `jp`, `sg`, `id`, `in`, `au`. The retired `any` value is refused. See [Targets](/reference/targets-yaml).
</ParamField>

### Deployment targets

<ParamField path="targets" type="object">
  Restricts where the package can be compiled or deployed. Its only key is
  `allow`. Omitting it adds no target restriction.
</ParamField>

<ParamField path="targets.allow" type="string[]" required>
  Any subset of `livekit`, `pipecat`, and `slng`. These are deployment
  providers, not target instance names. An empty list allows no target.
  Every target declared in the package is checked, even when a command
  selects only one of them.
</ParamField>

### Tools

<ParamField path="tools" type="object">
  Restricts tools by kind and identity. The available keys are `kinds`,
  `names`, `builtin`, and `slng`. Every applicable rule must pass.
  Permission does not create or attach a tool, and it does not add target
  support for that tool.
</ParamField>

<ParamField path="tools.kinds" type="object">
  Restricts execution kinds. Its only key is `allow`. Omit it to leave
  execution kinds unrestricted by the manifest.
</ParamField>

<ParamField path="tools.kinds.allow" type="string[]" required>
  Any subset of these eight values:

  | Value             | Tool kind                                                      |
  | ----------------- | -------------------------------------------------------------- |
  | `webhook`         | An HTTP tool                                                   |
  | `local`           | A local Python handler                                         |
  | `mcp`             | A tool provided by an MCP server                               |
  | `builtin`         | A built-in tool ID                                             |
  | `client`          | A client-side tool declaration; currently gated on all targets |
  | `provider_hosted` | A provider-hosted declaration; currently gated on all targets  |
  | `knowledge`       | A knowledge lookup                                             |
  | `slng`            | A named tool hosted on SLNG                                    |

  An empty list allows no tools. The ordinary target capability checks still
  apply; listing a gated kind here does not enable it.
</ParamField>

<ParamField path="tools.names" type="object">
  Restricts package tool names. Its only key is `allow`. Omission adds no
  package-name restriction.
</ParamField>

<ParamField path="tools.names.allow" type="string[]" required>
  Exact names from the package's `tools` list: for example, `check_booking`
  means `tools/check_booking.yaml`. Names are user-defined strings, with no
  wildcard matching. An empty list permits no package tools.
</ParamField>

<ParamField path="tools.builtin" type="object">
  Restricts builtin IDs in addition to any kind or package-name rules.
  Its only key is `allow`. This rule applies only to builtin tools.
</ParamField>

<ParamField path="tools.builtin.allow" type="string[]" required>
  Exact builtin IDs. Currently `end_call` is supported on all three targets;
  `send_sms` is supported only on SLNG. The manifest accepts nonempty ID
  strings, while tool validation checks whether the ID and target are
  supported. An empty list forbids builtin tools.
</ParamField>

<ParamField path="tools.slng" type="object">
  Restricts the identity of tools hosted on SLNG. Its only key is `allow`.
  This rule applies to a `slng:` tool on any target that uses it.
</ParamField>

<ParamField path="tools.slng.allow" type="string[]" required>
  Exact hosted tool names from `slng:`, which may differ from the local tool
  filename. Names are organization-defined strings. There is no wildcard or
  automatic discovery. The legacy pinned form uses the local package tool
  name. An empty list forbids SLNG-hosted tools.
</ParamField>

### Tracing

<ParamField path="tracing" type="object">
  Restricts the tracing provider when tracing is enabled. Its only key is
  `allow`. Tracing stays optional; this block does not turn it on or require it.
</ParamField>

<ParamField path="tracing.allow" type="string[]" required>
  Any subset of `langfuse` and `coval`. An empty list requires tracing to
  remain disabled. Omitting this block adds no provider restriction.
  Target support and credential requirements still apply.
</ParamField>

## Advanced

### Choose a different default

The first saved manifest becomes the default. Later creations offer to change it.
Plain `unmute init` uses that default and opens guided setup. Without a saved
default, it uses the ordinary creation flow.

This complete command changes the default for future agents:

```sh Terminal — select a saved default theme={null}
unmute manifest use acme-corp
```

Use `--manifest acme-corp` for one agent without changing the default.
Use `--from-manifest` to open a picker instead; it takes no name.
A broken default is an error unless you select a saved manifest directly.
Draft creation always requires an explicit agent name and `--manifest`.

### Edit the saved source

Saved contracts live under the operating system's user config directory at
`unmute/manifests/<name>/manifest`. The CLI prints the path after saving.
This complete command reopens the example contract:

```sh Terminal — edit the saved contract theme={null}
unmute manifest edit acme-corp
```

Saving replaces comments and formatting with clean YAML and first keeps an
exact backup beside the original. Both paths are printed. Unchanged edits
preserve the original bytes and create no backup. Revisions stay manual.

Use `--editor` only when you want external YAML editing or need to repair an
invalid saved file. See [external editor setup](/reference/cli/manifest).

### Update an existing agent's contract

When the contract owner approves a new revision, replace the package's
`manifest` with that approved file, then validate and compile again.
Keep its `manifest: manifest` link. Neither editing the library nor changing
the default performs this replacement for you.

## Validation and limits

The contract covers the whole declared package, including unused profiles,
fallbacks and every target override. Selecting one target for compilation does
not hide a violation in another target. Known violations fail before output is
written. Automatic or hidden language and region values that cannot be checked
produce warnings. Read those warnings; a successful compile does not prove
data residency. The compile report records the contract name, revision and
verification warnings.

Existing target capability checks still apply. Permission in a manifest does
not add provider support or make an unsupported setting work.

The creation console cannot collect custom model endpoint settings or a SLNG
Context Router upstream. It excludes those model choices. If your contract
allows only such bindings, use `--manifest <name> --draft` and complete the
package by hand or with a coding assistant. Validation and compilation still
enforce the same rules.

The contract checks declared settings, not arbitrary local tool code, the
provider's actual processing location or tracing delivery. It is not signed
and does not prevent somebody deleting both file and link. Pronunciation
dictionaries, compliance libraries, placement, URL restrictions, dependency
rules and prefetch limits are not part of this version.

## Troubleshooting

| Symptom                                             | Cause                                                      | Fix                                                                    |
| --------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------------------- |
| An agent violates a model rule                      | Its provider or model ID is not approved for that role     | Choose an approved pair; keep `slng` for SLNG-served models            |
| A provider's models are all blocked                 | Its `allow` list is explicitly empty                       | Ask the contract owner to add approved IDs or choose Allow all models  |
| A copied agent still follows old rules              | Each package keeps its own contract                        | Replace the copy with the approved revision, then validate and compile |
| Validation says the manifest is missing or unlinked | The file and `agent.yaml` link do not match                | Keep the root `manifest` file and `manifest: manifest` together        |
| A draft reports no targets selected                 | The assistant has not completed the package                | Supply the use-case brief and have it fill the required settings       |
| A permitted provider is unavailable in guided setup | The console cannot collect its endpoint or router settings | Use `--manifest acme-corp --draft` and follow the provider's reference |
| A region warning remains after compilation          | The declared location cannot be verified                   | Check the target's region support and the provider's configuration     |

## Where to go next

<CardGroup cols={2}>
  <Card title="Create the agent" icon="terminal" href="/reference/cli/init">
    Hand a manifest-backed draft to your coding assistant.
  </Card>

  <Card title="Edit company rules" icon="file" href="/reference/cli/manifest">
    Navigate the editor, save changes and manage backups.
  </Card>

  <Card title="Install the skill" icon="book-open" href="/reference/cli/skill">
    Give the assistant Unmute's authoring and validation workflow.
  </Card>

  <Card title="Read validation results" icon="check" href="/reference/cli/validate">
    Fix package errors before compiling.
  </Card>
</CardGroup>
