Skip to main content
A target is where your agent runs. Unmute compiles one package into a native project for the target you pick: Pipecat, LiveKit, or SLNG. Two are code targets, and one is hosted. Pipecat and LiveKit are code targets: unmute compile writes a Python project you own, host and run. SLNG is a hosted target: unmute deploy compiles a deployment body and pushes it, and SLNG runs the agent. There is nothing to host and no unmute dev. Those three are the only values provider accepts. On this page:

Targets YAML

targets.yaml
The key (pipecat, livekit) is the target instance name. It is what you pass to --target, and it becomes the directory name under build/. The name is yours: a package with two Twilio setups might call them pipecat_twilio and pipecat_telnyx.

Every key a target takes

One is required everywhere. The rest depend on the provider you chose.
livekit | pipecat | slng
required
Which runtime this instance compiles for. Those three names are the whole list. vapi and deepgram were target names once, and both are now refused by name.
exact framework version
The framework release an emitted project pins, written with all three numbers. Required on livekit and pipecat. Refused on slng, which owns the version its agents run on.
python
The language an emitted project is written in. python is the only value either driver has templates for, and LiveKit needs it stated to compile an MCP tool. Refused on slng.
package name to version
Package versions for the emitted LiveKit project, limited to names the LiveKit driver knows. Pipecat reads none of them, so leave it out there. Refused on slng.
connection file stem
The one connection file carrying this target’s phone calls. Required once the package declares a phone channel on livekit or pipecat, and refused when nothing in the package uses a phone route. Refused on slng, which has no carrier state in a package.
string or list of strings
LiveKit accepts us-east, eu-central, or ap-south, singly or in a duplicate-free list. Pipecat forwards one non-empty platform region. Both use platform placement when omitted. SLNG requires one of its 13 world parts; no default is inferred.
integer, zero or more
default:"0"
Instances the platform holds ready, so the first call after a quiet period is not waiting for a container to start. Pipecat only: LiveKit and slng refuse a stated pool. Left out means none, and the platform scales to zero when idle.
model entry name to a model definition
Per target overrides of named entries from agent.yaml. An override replaces the entry rather than merging into it. See Overrides, not forks.
A target says nothing else about telephony. It names one connection, and the connection file declares the transport, the carrier, and the environment names the route needs. The numbers a transfer dials live in agent.yaml under destinations:, because who you escalate to is the same desk whichever carrier reaches it.

Overrides, not forks

A target that cannot run a model as defined overrides that entry by name:
The agent does not change. One entry does. This is the shape of every per target difference, and it is why a package can serve both runtimes without a second copy of anything.

Switching a package to another target

unmute init scaffolds a LiveKit package: targets.yaml holds one livekit instance, and agent.yaml carries the turn detector that goes with it. Moving that package to Pipecat, or a Pipecat package to LiveKit, is two edits, not one. The target and the turn model travel together. This is the turn: block in agent.yaml, written for each one:
Point a Pipecat package at LiveKit and leave silero behind, and validate refuses before a file is written:
The other direction does not refuse. Pipecat forwards the turn binding as written and runs Silero either way, so a LiveKit turn model left in a Pipecat package is not an error, just a line of YAML that says something the generated project does not do. Fix it anyway. If you want to keep both targets rather than swap one for the other, do not edit agent.yaml at all. Leave the Pipecat binding in place and give the LiveKit instance the per target models: override shown above, which is what every shipped example does.

One package, two projects

Each directory is a complete project: source, pinned dependencies, Dockerfile, .env.example, and a runbook README written for that platform. --target limits the work:

Choosing between them

Both run the same agent. The differences that usually decide it: Running the generated project yourself differs too:
If you need warm transfer today, that is the LiveKit SIP route. If you want a phone number with nothing hosted, that is one of the Pipecat routes. For a browser agent, either.

Where to go next

The Pipecat project

What build/pipecat/ contains.

The LiveKit project

What build/livekit/ contains.

The SLNG deployment body

What build/slng/ contains, and what SLNG runs for you.