Skip to main content
Every release of the Unmute CLI, newest first. Each entry is that release’s notes as published, and it links to the release on GitHub, where the binaries, the checksums and the full commit list live. An entry describes the release it shipped with, not how Unmute behaves today. The guide is the current answer. Where an entry mentions the Context Router, the Context Router page is the page that explains how the router decides which turns to treat as repeatable, and which upstream kinds were validated live here.
CLI
v0.7.3
Dev page Metrics fixes and a working Claude skill install.How to upgrade:
  1. Upgrade unmute: brew upgrade --cask slng-ai/tap/unmute.
  2. If you use Claude, run unmute skill install --agent claude again. You do not need to compile your agents again.
Fixes:
  • Metrics view: each reply now sits on the caller turn it answers. Before, a reply was shown on the turn before it, and the last turn showed ”, ”. This affected typed calls and mic calls on LiveKit.
  • Metrics view: when you open a turn, its parts are now listed in the order they started. Before, they were grouped by type. A tool turn now reads the way it ran: LLM, tool, filler speech, LLM, tool, reply.
  • unmute skill install --agent claude now also writes the shared skill files under .agents/skills/. Before, it wrote only the .claude pointers, and they pointed at files that did not exist.
Full notes and downloads
CLI
v0.7.2
A new dev page with metrics, state and text chat, plus runtime fixes.How to upgrade:
  1. Upgrade unmute: brew upgrade --cask slng-ai/tap/unmute.
  2. Compile your agents again. The generated Pipecat and LiveKit projects changed: call_state.py, pyproject.toml and the LiveKit agent.py.
Highlights:
  • The unmute dev page has a new look, in the style of SLNG Studio. It has a top bar, a call bar, a transcript with a speaker column, and a side panel with call details.
  • New Metrics view. It shows p90 tiles and one row per caller turn, with the time for each part: STT, LLM, TTS and tools. Open a turn to see each part on its own row. Latency by model is grouped by STT, LLM, TTS, and tools and handoffs.
  • Reply latency colours: green up to 900ms, yellow up to 1200ms, orange above. Red now means failed only. Turns with tool calls are not rated. A legend explains the colours.
  • Live call state. Every save to State shows as a row in the conversation, with what set it and the value before. A new State panel lists every field from state.py with its current value.
  • Type to the agent. During a call, a text box under the conversation sends a line as the caller’s turn. A new Text only button starts a call with no microphone.
  • A start screen shows progress while the agent starts. If the start fails, it shows the first error and a link to Logs.
Fixes:
  • unmute dev --target pipecat no longer fails at startup for a package with knowledge: on Linux. Generated projects now tell uv to copy packages, not hard-link them.
  • A LiveKit worker behind HTTPS_PROXY now connects to its server directly when NO_PROXY lists the server. Before, the proxy answered 405 and the worker gave up.
  • Pipecat reply latency is now linked to its reply. Before, every Pipecat turn in Metrics showed ”, ”.
  • On LiveKit, a hang-up during a task is now recorded as cancelled, not failed.
  • The docs changelog workflow works again. It now opens a pull request after each release.
Examples:
  • New examples/salon-concierge-unoptimized. All three salon examples now use the same model, tools and turn-taking. You can compare their token use directly. salon-concierge uses 36 to 45% fewer tokens than the unoptimized one.
  • scripts/text_run_livekit.py now prints token usage.
Privacy note: the dev page and build/<target>/dev.log now show state values. These can include tool results and caller details. They stay on your machine.Run unmute skill install to refresh the bundled assistant guidance.Full notes and downloads
CLI
v0.7.1
SLNG deploy fixes.How to upgrade:
  1. Upgrade voiceai: brew upgrade slng-ai/tap/voiceai. Deploy needs voiceai 0.1.22 or later.
  2. Upgrade unmute: brew upgrade --cask slng-ai/tap/unmute.
  3. Compile and deploy your SLNG agents again.
Fixes:
  • end_call: the caller hears one goodbye, not two. The announce: on end_call is now the goodbye line itself.
  • Inbound calls no longer fail when a prompt uses a call fact, such as from_number.
  • A package that also targets LiveKit or Pipecat no longer fails to deploy because of world_part.
  • Deploy works again after api.slng.ai went offline.
  • A dry run no longer refuses an MCP server whose snapshot is old.
New:
  • Deploy warns you when inbound phone calls are not ready.
Changed:
  • The deploy report drops organisation (report_version 2).
Run unmute skill install to refresh the bundled assistant guidance.Full notes and downloads
CLI
v0.7.0
Call state in state.py, and tasks on SLNG managed agents.How to upgrade:
  1. Upgrade voiceai: brew upgrade slng-ai/tap/voiceai. Deploying a task that lists tools needs voiceai 0.1.20 or later.
  2. Upgrade unmute: brew upgrade --cask slng-ai/tap/unmute.
  3. Install uv (https://docs.astral.sh/uv/) if a package has variables. unmute now reads state.py with it. The first run needs network.
  4. Run unmute validate on each package. Every old form is refused with its file, its line and where it moved. The fixes are below.
  5. Run unmute compile and deploy.
Breaking changes:
  • The call state is a Pydantic model in state.py. Why: types, defaults and descriptions are now real Python that Pydantic checks, not a type grammar inside YAML. How: move each variable’s type:, default: and description: to a field on class State(BaseModel) in <package>/state.py. variables: in agent.yaml is now a list. It keeps only the values that need source: or confirm:.
    The old form fails with: variables: is a list now. Types, defaults and descriptions live on State in state.py.
  • shapes: is gone. Why: a shape is a type, and types now live in state.py. How: write each shape as a BaseModel class in state.py and use it as a field type on State.
  • Templates name a saved value as {{state.x}}. Why: the name now says where the value lives, a field on State in state.py. How: change {{x}} to {{state.x}} in the greeting, prompts, tool inject:, webhook path: and prefetch args:. {{$NAME}} is unchanged. The old form fails with: {{x}} names a value on State; write {{state.x}}.
  • A step must return every value its assign: names. Why: every field that starts empty is now | None, so | None can no longer mean “the step may leave this out”. How: add ? to a value the step may skip: - callback_time: result.callback_time?. Lists (x+:) stay optional. Nothing fails at validate, so read each assign: once.
  • Pipecat needs params.world_part on SLNG speech. Why: pipecat-slng 0.6.0 made it required, and a Pipecat bot without it failed at start. How: add world_part: eu-north (or your region) under params: on each SLNG listen and speak binding. unmute validate refuses a Pipecat package without it. LiveKit is unchanged. The SLNG target drops world_part, so one package can target Pipecat and SLNG.
New:
  • Tasks and task groups on SLNG managed agents. Why: SLNG managed agents now run tasks. How: write tasks the same way as for LiveKit and Pipecat, and add slng to the targets. A tool that only a task uses is attached hidden from the main agent. unmute validate names what SLNG still refuses: a model per task, finish: rules, history: summary, a group ending in anything but return, and handoffs.
  • Typed values on SLNG. A value a task saves, or one the model records with source: conversation, can be a phone number, email, date, time, Literal, list or model. A value the dispatch fills stays plain text.
  • Logfire tracing on LiveKit and Pipecat: tracing.provider: logfire with LOGFIRE_TOKEN. Langfuse and Coval settings are unchanged. LiveKit no longer installs the langfuse SDK, and its traces drop the empty wrapper rows.
Generated code:
  • Generated Python passes its own ruff and ty rules. Each project carries them in pyproject.toml.
  • Each code target writes a small project instead of one big file: settings.py, session.py, agents.py, call.py, utils/, and prompts in prompts/*.md. Twilio splits app.py the same way. The entry file keeps its name (bot.py, agent.py, app.py), so deploy commands do not change. If you edited a generated file by hand, find your edit in the new layout.
  • The saved call state is a real Pydantic model at runtime. A saved model holds a model, not a dict. Call-start values and carrier facts now go through the same check as every other save.
Full notes and downloads
CLI
v0.6.1
Voice agents on Twilio, with SLNG optimization by default.Highlights:
  • Twilio is now a compilation target. Turn your agent spec into a standalone FastAPI application for inbound ConversationRelay calls. Twilio handles speech recognition and synthesis; your app manages conversation history, tools, and streamed model responses.
  • Start with unmute init my-agent --target twilio. The starter uses SLNG Context Router with OpenAI upstream to reuse eligible responses and send other requests to the model. Direct OpenAI and Gemini bindings are also supported.
  • Host the generated app wherever you choose, then connect your number with unmute deploy --target twilio. Deployment checks the hosted build and signed webhook, saves the previous route, and updates the number. Use --dry-run to check before making changes.
  • The generated app includes signature validation, streamed replies, interruption handling, local tools, end_call, health checks, and graceful shutdown. Custom Python logic and post-session TwiML let you control what happens during and after a conversation.
  • A first-call walkthrough covers Twilio account setup, getting a number, compiling locally, publishing the app, and connecting it. Hosting examples show container services, a VM, and a laptop tunnel.
  • The shipped example was verified on a deployed application with a real phone call through SLNG, including an opening-hours tool call and a clean hangup.
Getting started: unmute init my-agent —target twilio cd my-agent unmute validate unmute compileFollow the guide to host the app and connect your number: https://unmute.ai/telephony/twilio-conversation-relayRun unmute skill install to refresh the bundled assistant guidance.Full notes and downloads
CLI
v0.6.0
Pipecat steps that start on the caller’s words, one trace per call, and prompts checked against replayed calls.Highlights:
  • Pipecat: a task step now opens on an instruction. It speaks its opening line first, then gives the model an instruction that points at what the caller already said. Before, the request ended on the model’s own sentence. The model then asked again for details it had, sometimes invented a value, and sometimes returned nothing. That last case left the caller in silence. Without any instruction, a step acted on a request before asking for a yes.
  • Pipecat tracing: two calls on one worker stay apart. Per-call state lives in a context variable now. A warm worker no longer files one call’s spans under another call’s session.
  • LiveKit tracing: one call is one trace again. The event loop monitor sent an event_loop_blocked span with no parent when the loop stalled for more than 100 ms. That span could split a call into two traces. It is no longer exported.
  • Every Pipecat build answers the Twilio route of the runner. A browser-only example can now take a simulated phone call too.
  • {{$NAME}} in a prompt or greeting now fails unmute validate on every target. On slng it used to pass validation and then fail at push, because the backend removed org variables on 2026-09-02. The error says where a Vault token still works: an MCP server URL. A tool still names its secret by bare name in auth:.
  • The salon prompts were fixed where replayed calls showed them wrong. The agent asks for a number it does not have instead of inventing one. It reads back a number given in pieces once, whole. It runs verification before it records a complaint, so it never says it saved something it did not. It no longer offers a transfer nobody asked for.
For contributors:
  • make sim TEST_SET=<id> runs one Coval test set against the examples running on your laptop, on both LiveKit and Pipecat. It exits 1 when a call did not finish, the agent never spoke, or a metric said NO. See utils/coval_sim/README.md.
  • scripts/text_run_pipecat.py drives a compiled Pipecat bot through scripted caller lines. It uses the real model and the local tools, with no audio. It takes the same flags as text_run_livekit.py.
Upgrade notes:
  • Recompile. The Pipecat bot template and both tracing templates changed.
  • If a prompt or greeting uses {{$NAME}}, move the value into a package variable ({{name}}) or into the MCP server URL. It was already refused at push on slng. Now validate says so first.
  • Run unmute skill install again. The skill’s package and deploy references changed with the Vault token rule.
Full notes and downloads
CLI
v0.5.6
Task groups that speak on Pipecat, a booking turn that costs one request less, and a docs tree that stopped rotting.Highlights:
  • Task groups work on Pipecat. A step’s opening line was emitted as a Flows tts_say pre-action, and a pre-action holds the node until the frame behind it reaches the worker sink, a frame this worker queues does not move until the tool call building the flow returns. The first node of every flow waited on itself: nothing spoken, nothing asked of the model, the caller left hanging. It is a queued TTSSpeakFrame now, so nothing waits. opening: listen was broken the same way and is fixed by the same change. Two runtime smokes hold it; both time out on the old template.
  • The salon’s book group is back, and a booking turn spends one model request fewer. manage_booking loses its when:, so the group is the only way in, and skip_when_confirmed: decides verification again. That is the general shape, now written down at /build/orchestration/task-groups and in the skill: two tasks an agent chooses between spend a request on the choice, and that request speaks nothing and does nothing. A group is chosen once, and every step after the first opens by itself.
  • The Vertex bridge emits HttpOptions with the enum. ty reads a plain dict as dict[str, str] and refuses "COLLECTION" where a ResourceScope belongs, which is what turned the salon’s static check red. One const, so Pipecat gets it too, and the request on the wire is the same string it was.
  • docs/ is one file. GATES.md, HARNESS_TEST.md and SELF_VERIFY.md each restated something the code, the tests or CLAUDE.md already said, so they rotted against it instead of holding it. ARCHITECTURE.md stays, it is the one file that describes the system boundary, the four compiler stages and each target’s runtime topology in one place, minus the interactive console. The allow-list test now refuses any other tracked file under docs/, so a second one stays a deliberate decision.
Upgrade notes:
  • Recompile. The Pipecat template changed, and a package built before this still has a first node that waits on itself.
  • Run unmute skill install again. The skill now says to reach for a group before two tasks with a when: each, and says why.
  • Nothing in agent.yaml has to change. If you split a group into separate tasks to work around the silence, put the group back.
Full notes and downloads
CLI
v0.5.5
A skill for the push, curated capabilities from the package, and telephony you can read.Highlights:
  • A third skill, unmute-deploy. Pushing is a different job from building, done at a different time and often by somebody who did not write the package. It carries the command loop, what each of the two dry runs checks, how to read the detach list, and what a push replaces against what it leaves alone. That last list is the fourteen fields of the compiled body, held to the code both ways.
  • unmute deploy attaches a curated capability named by a slng: reference. It used to refuse, send the author to the dashboard, and the next push detached what the dashboard attached. voiceai agents push accepted the same body all along, so the refusal was ours: three gates, and the organisation-only scope filter alone was enough to stop a curated record, which is global.
  • current_datetime and user_phone_number join the prebuilt registry, now four ids, and inject: pins the settings each one takes. A package can pin a timezone the curated tool cannot carry. announce: is legal on a prebuilt on SLNG. The registry and its settings are written down at /build/tools/prebuilt.
  • A tool that ends the conversation waits for its own announce: line. end_call hangs up the moment it runs, so a goodbye spoken alongside it was cut off mid-word. Every other announcement still runs alongside the tool.
  • Seven refusals found by deploying one package: a {{placeholder}} for a source: conversation variable (it reached SLNG as a fieldless 422), an omitted provider: under a manifest, a prebuilt whose id is not its file’s name, one name held at two scopes, and a placeholder in a prompt now names its line. The deploy preview compares every setting the package pins, so pinning a timezone no longer reads as deleting it.
  • telephony-setup.sh is gone. It called bare lk, which has no project flag, so on a machine pointed at another project it created the trunk and the dispatch rule in the wrong account and printed success. Compile still writes the two JSON files; the runbook prints the two commands that send them, each naming its project. The Twilio and LiveKit pages are rewritten in step order, with a symptom table, a teardown and a what-to-redo table.
  • The salon concierge sounds like a person. Nine passages read like incident reports written to the model on every turn; every rule stayed, every incident went to the README. Behind it, the realism guidance now puts a frequency budget on each technique: at most one filler in a turn, none in most, and a clean grammatical sentence is no longer labelled bad.
Upgrade notes:
  • The company contract is manifest.yaml now, in a package and in the saved library. A package still holding the old extensionless manifest is refused by name. A library saved before this keeps loading.
  • Run unmute skill install again. The bundle writes three skills.
  • If you ever ran telephony-setup.sh, check which LiveKit project holds the inbound trunk and the dispatch rule before you dial.
  • Recompile to pick up the goodbye before the hangup and the new refusals. Nothing in agent.yaml has to change.
Full notes and downloads
CLI
v0.5.4
Plain init, a skill for company rules, and templates in their own repo.Highlights:
  • unmute init <name> writes six files and asks nothing again. A saved default manifest was routing every new package into guided setup, so a new agent could not be created without answering for a contract nobody had asked about. --from-manifest is now the one way a contract reaches a new package.
  • A second skill, unmute-manifest, writes the company contract. An assistant cannot run the picker, so it does the part that is words: ask what the company allows and write the YAML. unmute manifest create <name> --file draft.yaml saves it, validates before it saves, and writes nothing when it refuses.
  • The salon concierge thinks with Gemini 3.1 Flash-Lite on Vertex in eu, at thinking_level MINIMAL to keep the first token fast. The old OpenAI block stays commented in the file, so switching back is one edit.
  • Templates live in slng-ai/unmute-templates. The single copy kept here is gone, and the README, CONTRIBUTING.md and the skill a coding agent reads point at that repo and say what a template carries.
Upgrade notes:
  • Replace unmute init <name> --manifest <name> with unmute init <name> --from-manifest and pick from the list. The --draft flag is gone, along with the assistant draft flow it served. The unmute console and manifest use keep the default.
  • Run unmute skill install again to pick up unmute-manifest. The bundle now writes two skills.
Full notes and downloads
CLI
v0.5.3
Alternating announce lines, a reworked salon, and steps that don’t repeat.Highlights:
  • announce: takes a list. The caller hears one of those lines each time it fires, never the one that site used last, so a flow entered twice in a call does not sound like a recording. A single line still works and needs no change.
  • A task speaks its announce as the step is entered, whichever way the step was reached. On a tool the line sits in the tool body and fires once per call, so two calls in one turn played it twice.
  • A step the caller has not spoken since is refused instead of run again, on LiveKit and Pipecat. A finished result with no new caller turn above it is the model re-reading its own work.
  • LiveKit sessions retry the model once instead of four times. The default sleeps 4.1 seconds before it gives up.
  • Rework the salon concierge: seven tools instead of eleven, two plain tasks instead of a task group, and the saved booking now carries the sentence the agent reads out loud.
  • Fix a LiveKit call arriving as two Langfuse traces, and name a tool call after its tool on both targets.
Upgrade notes:
  • Recompile to pick up the refusal and the retry cap. Nothing in agent.yaml has to change.
  • A task group still compiles but speaks nothing on Pipecat. Use plain tasks there until that is fixed.
Full notes and downloads
CLI
v0.5.2
Speech-to-speech agents, better manifests, and clearer deployment guides.Highlights:
  • Add realtime and live architectures on LiveKit and Pipecat. Run speech-to-speech agents, or pair a realtime model with a separate speech synthesizer. Existing packages default to cascade.
  • Add pharmacy-refills and takeaway-orders examples with local tools and knowledge lookup.
  • Improve the manifest editor and create agents from saved company rules with unmute init —manifest or —from-manifest.
  • Fix LiveKit tool inputs, Pipecat task history, delegated tool timing in the browser, and the Homebrew postflight warning.
  • Explain architecture choices, workflow limits, and deployment steps for LiveKit Cloud, Pipecat Cloud, and SLNG.
Upgrade notes:
  • Set the LiveKit framework version to 1.8.1 and Pipecat to 1.10.0 in targets.yaml.
  • Realtime and live currently support single-agent browser calls. Keep cascade for tasks, saved state, tracing, and phone routes.
Full notes and downloads
CLI
v0.5.1
Google inference locations on LiveKit and Pipecat.Highlights:
  • Choose Google Vertex inference locations with params.location. US, EU, individual regions and explicit global routing now select the corresponding Google endpoint on both LiveKit and Pipecat.
  • Keep GOOGLE_API_KEY authentication and provider parameters, including thinking_config. Existing EU routing and Gemini Developer API configurations continue to work.
  • Follow Google’s endpoint rules without a compiler region allowlist. Unsupported locations and unavailable models fail at the requested endpoint, with no fallback to global or another region.
  • Verify real US requests through both generated native clients. Regression checks cover endpoint selection, parameter forwarding, mixed locations, Developer API behavior and provider errors.
  • Update the model guide and coding-agent skill reference with location examples and routing behavior.
Full notes and downloads
CLI
v0.5.0
Reusable company rules, native Gemini, and unified regions.Highlights:
  • Reuse company rules with unmute manifest. Guide new agents through allowed models, languages, regions, targets and tools. Each package carries its own manifest for offline validation and compilation.
  • Run native Gemini on LiveKit and Pipecat, including Vertex EU access with an API key. EU requests use the regional endpoint with no global fallback.
  • Use one set of 13 SLNG regions across deployment, speech and the Context Router. Listening, thinking and speaking now share params.world_part.
  • Build with clearer guides: a first-task walkthrough, complete field references, practical credential setup and example troubleshooting. New checks catch broken links, invalid MDX and missing field docs.
Upgrade notes:
  • Replace the Context Router’s params.world_part_override with params.world_part. Choose a current region such as eu-west or us-east; the old eu, us, india and indonesia values are refused.
  • Update SLNG deployment_region values any, eu-central and ap-south to a supported region. LiveKit now rejects unknown worker regions and media region groups used as deployment regions.
Full notes and downloads
CLI
v0.4.2
Regional speech, live transcripts, and typed contacts.Highlights:
  • Choose where SLNG speech requests go. Set params.world_part on each SLNG listen or speak model to select one of 13 regional gateways, including eu-north, eu-west, us-east and us-west. Unmute generates the matching endpoint on both LiveKit and Pipecat. Gateway location and worker deployment region are configured separately.
  • See every turn in unmute dev. Streaming transcripts show the caller’s words and the agent’s reply as they arrive. Model requests, tool calls and handoffs get their own rows, with per-request latency and audio timings to help explain where the wait comes from.
  • Collect typed contact details on LiveKit and Pipecat. EmailStr checks and normalizes email addresses before saving them. NameEmail keeps a name and address together, with dotted references for either field. Invalid values leave saved state untouched and tell the model what to correct.
  • Deploy SLNG tools by name. Reference published hosted tools and named MCP tools without pulling a mirror first. Deployment checks published contracts, injected arguments and required credentials before pushing. A dry run previews the versions and attachment changes.
  • Record conversation values and send SMS on SLNG. The new source: conversation lets the model save values during a call. The send_sms builtin sends a message to the caller’s number on phone calls, with the sender fixed by the package.
  • Two new examples to build from. customer-intake shows typed details, caller confirmation and saved values passed into a local tool. hotel-concierge replaces slng-support with hosted lookups, MCP web search, conversation memory and SMS summaries.
  • Run local dev sessions side by side. Busy default ports are selected automatically, LiveKit stacks are isolated, and shutdown cleans up the session. Transcript handling, worker startup and Pipecat hangups also get fixes.
  • Updated dependencies and clearer guides. pipecat-slng moves to 0.5.2, generated Python supports ty 0.0.40, and the docs expand SLNG deployment, typed state, regional model settings and latency measurement.
Upgrade notes:
  • For SLNG listen and speak models, replace params.world_part_override and params.region_override with params.world_part and a specific gateway, such as eu-north. Legacy values na, eu and ap are refused. Omit world_part to keep the default endpoint. SLNG think models keep the Context Router’s existing world_part_override setting.
  • SLNG deployment requires voiceai support for checked, resolved pushes (verified with 0.1.18). Validation and compilation remain offline.
Full notes and downloads
CLI
v0.4.1
Simpler SLNG deploys, live transcripts, and a hotel concierge.Highlights:
  • Reference SLNG hosted tools and MCP tools by name. Deployment checks published bindings and credentials, previews attachment changes, and pushes only after checks pass.
  • Follow conversations as they happen in unmute dev, with streaming transcripts, tool activity, and per-request latency.
  • Meet hotel-concierge: a new SLNG example combining hosted tools, web search, conversation memory, and SMS summaries.
  • Improve local worker startup, transcript handling, and graceful Pipecat hangups, with regression coverage for LiveKit task handoffs.
  • Update pipecat-slng to 0.5.2 and keep generated Python compatible with ty 0.0.40.
  • Expand the SLNG deployment walkthrough and clarify tool setup, testing, and latency measurement.
Upgrade note: SLNG deployment now requires voiceai support for checked, resolved pushes (verified with 0.1.18). Validation and compilation remain offline.Full notes and downloads
CLI
v0.4.0
Typed state, simpler tasks, and portable hosted tools.Highlights:
  • Typed session state on LiveKit and Pipecat. Declare reusable shapes, lists, optional values and fixed choices. Task finish arguments come from the variables they assign, so each type is declared once. Results are validated together before any value is saved.
  • Explicit context sharing. Prompts read saved values with {{variable}} or {{variable.field}}. Tasks restore the owner’s earlier context and return a completion status; saved results reach only prompts that name them. List assignments can append records across several tasks.
  • Simpler task definitions. Tasks live inside the agent that owns them, with their trigger, announcement and assignments in one place. Other agents can reuse a task by name.
  • Hosted SLNG tools. The new slng: block references an existing tool, and unmute pull saves its definition and hash into the package. Validation and compilation check the committed mirror offline. Supported mirrors also run in generated LiveKit and Pipecat projects.
  • Langfuse v4 tracing on both code targets. Each call stays in one trace, with the full conversation on its root and both sides of each exchange on a turn span. Tool spans carry their names, arguments and results; session IDs and trace names reach every observation.
  • More reliable conversations. Pipecat settles task tool calls before returning to the owner, starts replies after empty-history handoffs, and removes tool calls together with their replies when trimming history. Salon examples preserve verified identity and booking details across changes. A new text harness exercises generated LiveKit agents with real models and local tools.
  • Clearer CLI output and docs. Commands print what they did and what needs fixing; compile details live in compile-report.json. New guides cover state design, context sharing and verification. Shared OpenAI bindings can select LiveKit’s Responses API; Pipecat warns and drops the options it cannot use.
Breaking changes and migration:
  • Replace agent model: and voice: selectors with think: and speak:. Task model overrides also use think:.
  • Move top-level task definitions into an agent’s tasks: list. Replace delegates: with tasks: or task_groups: attachments, moving triggers and announcements onto the task or group.
  • Replace task result: schemas with typed variables and task assign:. Write assign: and tool inject: as lists of single-key entries.
  • Remove requires: and handoff context.variables:. Put step ordering in prompts and reference saved values explicitly. Tools still refuse missing or unconfirmed injected values.
  • Omitted task and handoff history now means messages. Use full when the receiver needs earlier tool calls and results.
  • Move package-level timezone: onto each clock pre-fetch entry. Replace tool read_only: with an explicit writes: false or writes: true on each tool pre-fetch entry.
  • SLNG deployment no longer creates tools from local: or webhook:. Create the tool on SLNG, reference it with slng:, run unmute pull, and commit the generated mirror. Local and webhook tools remain supported on LiveKit and Pipecat.
Full notes and downloads
CLI
v0.3.2
Pre-fetch known facts, and a deploy that checks the account first.Highlights:
  • prefetch: resolves known facts before the greeting. A package declares an ordered list that reads three sources: clock: (a date under the package’s timezone:), source: (a call fact the carrier supplies) and tool: (one read-only lookup, keyed on a value an earlier entry assigned). Each entry gets a 2s budget and cannot raise: a skip leaves the variable on its default and the existing guard runs the step that asks. confirm: marks a value the caller has not agreed to yet, so it renders in no prompt but its confirming step’s and satisfies no gate until it is settled. announce: on a delegate covers the entry gap, spoken after the guard so a refused step stays silent. unmute dev --source from_number=... seeds a call fact into the browser loop, which has no carrier. Salon is rebuilt around it and get_current_date is gone. A package declaring none of the new fields emits byte-identical output.
  • unmute deploy checks the account before it writes anything. It asks the organisation what it already has, compares it with what the package needs, and reports every gap in one pass with the line that asked for it and the one action that fixes it. Checked: every builtin: tool, every MCP server and exposed server tool, and every vault secret and variable including whether it holds a value. A code or webhook tool is never reported missing because the push creates it. Secrets are filled by handing the prompt to voiceai secret create, so no value enters unmute or reaches argv. A refused run leaves build/ and the account untouched. Adds unmute resources and --call.
  • mcp: is core on slng. voiceai 0.1.16 resolves a reference by server name and copies each tool’s schema hash from the platform’s own snapshot, so nothing connects to the server; unmute warned the opposite and told authors an mcp: package could not deploy at all. Both were wrong. Adds mcp.server for a platform name carrying a dash or a space. Proven on a live deploy.
  • An agent declares what it can do in tools:, delegates:, handoffs: and escalations:. The block a thing is written in is its kind, so kind: and controls: are gone. A strict re-spelling: every package compiles byte for byte identical on every target.
  • Tracing: salon-concierge moves to Langfuse, and scripts/read_langfuse_trace.py reads a unmute dev call back out of it, transcript, tool calls and per-span latency, newest trace by default. Coval self-verification is push-based and is unaffected.
  • Docs: two new pre-fetch pages (the primitive, and how to decide what to pre-fetch), one page that explains the shape of a package before Orchestration needs it, and our own measured costs are out of the reader-facing pages.
Breaking:
  • controls: and kind: are removed with no alias. An old package fails as an unknown key, with file, line and column.
Full notes and downloads
CLI
v0.3.1
One deploy command, deployment names that stop colliding, and honest Coval traces.Highlights:
  • unmute deploy [package-dir] validates, compiles and pushes a package to SLNG in one command. It shells out to voiceai agents push --json, so the push contract stays in one released binary. A refused push relays every problem with the fix line and the dashboard page. Credentials come from SLNG_API_KEY, then VOICEAI_API_KEY, then a stored voiceai login profile, read from the package’s own .env, and the organisation is printed every run.
  • Deployments are now named after the package, not the target. Before this, every package deployed as slng, livekit or pipecat, so a second package replaced the first one’s live agent and two LiveKit packages split one worker’s dispatch. agent.yaml now requires name:, and a deployment is that name joined to its target. This also fixes unmute dev, which minted a browser token for a room nothing ever joined.
  • Coval traces are per call again. Pipecat Cloud serves many calls from one warm container, and every call after the first was filed under the first call’s conversation with nothing logged either way. Correlation now resets on every call, late spans are dropped instead of misfiled, local runs label themselves <name>-local, and one accurate log line replaces the message that claimed no trace was exported when one was.
  • Pipecat support raised to 1.8.0, with pipecat-slng >= 0.5.1. 0.5.0 imported a private name that 1.8.0 renamed, which broke every emitted bot at import.
  • The salon concierge example sounds like a person. Prompts now separate the speech contract from the personality, leave numbers, money and times in plain written form so the voice engine normalizes them, and drop the second acknowledgment that talked over each tool’s announce line. Three defects came off a live call, and the evidence sits next to each rule. The skill teaches the same shape.
  • Docs: a runbook for the second deploy, including the routing records a rename strands, on every target’s own page.
Breaking:
  • agent.yaml must carry a name:. A package without one is refused with the shape and an example.
  • Deployed identities change name, so the first deploy after this upgrade creates a new agent and leaves the old one live. Delete the old one.
Full notes and downloads
CLI
v0.3.0
Compile to SLNG, knowledge search, and turn timing you can set.Highlights:
  • New slng target: compile a package straight to the SLNG platform.
  • Knowledge bases: point a tool at your own documents - txt, md or pdf files.
  • Turn timing is yours to set. endpointing_delay is the silence floor, pace is the ceiling, and semantic_endpointing can switch the turn model off.
  • Pipecat phone calls are faster and quieter: warm_instances keeps containers warm, and the agent no longer interrupts its own greeting on speakerphone.
  • Faster turns on both targets, from pipecat-slng 0.5.0 and the quicker SLNG route.
  • Context Router sends model settings per request, and prompt_suffix adds one line to every prompt in a package.
  • Task groups: a step that returns can carry its own prerequisites.
  • Console rebuilt on Bubble Tea and Lip Gloss, with one owner for colour.
  • Versioned docs, a full carrier setup guide, and a changelog that writes itself.
Breaking:
  • The vapi and deepgram targets are retired. deepgram is still a model vendor.
  • Local telephony testing is gone. Test phone calls on a deployed agent.
Full notes and downloads
CLI
v0.2.5
Per-site Context Router cache scopes.Fixes a cache collision where agents sharing one authored agent_id could be served each other’s cached replies. The router keys its cache on the last exchange with no system prompt, so in a multi-agent package a specialist’s opening turn could get the concierge’s cached line.Highlights:
  • Every prompt site now gets its own cache scope derived from the authored id: “<id>:<agent>”, “<id>:task.<name>”, “<id>:summary”. Authoring is unchanged: still one agent_id per package.
  • LiveKit sets the header per request in an emitted _slng_llm_node, since constructor-level extra_headers would replace per-request values.
  • Pipecat switches scope on task entry and restores the owner’s scope on every exit path: finish, next step, transfers, terminal node, and error rollback.
  • New gates: one scope per prompt site on every target, no constructor extra_headers on LiveKit, scope restore on each Pipecat exit path, and the name pattern excludes the scope separator.
Full notes and downloads
CLI
v0.2.4
A phone call that works, a dev loop that shows the numbers, and a faster LiveKit turn.Highlights:Local telephony you can test end to end The (pipecat, sip) inbound route compiled and passed its goldens but could not answer a phone. Six defects, each found by placing a real call against the local SIP plane: no telephony.py for the containers uvicorn CMD, no route telling the bot about a call, telephony-setup.sh emitted without the JSON files it reads, a two-phase startup that created trunk records against a server that was not running, a greeting that waited on an RTVI handshake no phone call fires, and a hangup handler installed on an event the transport does not have. Cold transfer now reads the participant identity off the room instead of passing a sid the platform answers 404 for. salon-concierge ships a pipecat_sip target on the same trunk as its livekit target, so the docs are one command again instead of “copy this other example and edit two files”. Three telephony pages merged into one dev/local-telephony page with redirects, and first-phone-call is now inbound-calls to pair with outbound-calls. Two test gates got honest: the live-call banner test no longer reads the real PATH for sox, and the barge-in gate reads its counters under the lock that writes them, so it stops failing a call where the barge-in actually worked.Metrics, logs, and tool timings in the dev UI Every emitted project now carries dev_metrics.py and prints one framed JSON line per turn to stdout. No collector, no exporter, nothing over the network. internal/devmetrics owns the lines shape and is the only decoder. The producers stay inert unless UNMUTE_DEV_METRICS is set, and the artifact is byte-identical with the switch on and off. The switch now also reaches the containers that run an agent, which is why the LiveKit half shipped wired correctly and never switched on. The dev page gained a logs view fed by server-sent events, and the listener now binds before the target starts, so a failed container build is visible instead of invisible on exactly the runs whose output you need. Output produced before the browser loads is replayed on connect, and Last-EventID is honoured so a reconnect resumes rather than repeats. Each agent turn carries its own timing line: end to end, time to first byte per service, and how long the reply took to stream. Every tool the turn called gets its own row above the reply it delayed, which is where it happened in the timeline. Handoffs are no longer reported as tools: a LiveKit delegate that does not return until its whole flow finishes was reporting as a single 51-second tool call. An unreported value renders as a dash and never as 0.00. The transcript shows one row per spoken turn instead of one per recognizer fragment, which was nine rows for one sentence on gradium/stt:default. The mic control states which of three things is true, M toggles it, and holding SPACE talks, so barge-in can be tested deliberately. New docs page under Develop and test explains where the time goes in a voice turn, with field meanings read from pipecat 1.7.0 and livekit-agents 1.6.10 themselves.Coval as a first-class tracing integration tracing: provider: coval compiles to a project that sends Covals canonical spans on both code targets, with no correlation code written by the package author. Both of Covals correlation routes are used: a call Coval placed exports against the simulation ID on the call, and any other call is registered as a Coval conversation when it ends and exports against the conversation ID that comes back. That second route is what puts a local unmute dev run in Covals Trace Search. Spans are held, capped, and flushed once an ID arrives, so nothing before correlation is lost. The two targets reach the span tree differently, because the frameworks differ. Pipecat already nests its spans the way Coval wants, so they are renamed in flight. LiveKits shape cannot be fixed by renaming, since a spans parent is fixed when it starts, so the LiveKit module leaves LiveKits own OpenTelemetry off and builds Covals tree from session events, using only numbers LiveKit measured itself. Each llm span carries the prompt that round actually ran on, under the same attribute names on both targets. A number that was never measured is left off rather than sent as zero.LiveKit turn latency, measured across three calls per setting A session of live latency work on salon-concierge, with every claim taken from three calls rather than one, because two calls on an identical build differed by 1.1s of mean silence.
  • The transcriber, not any endpointing number, was buying a two-second penalty per turn: a turn whose transcription_delay reached 1.0s got the 2.5s max_delay instead of the 0.58s floor. deepgram/nova:3 finalises in 0.159s mean against gradiums 0.999s, with the same words in every transcript.
  • endpointing_delay now sets the silence window it always claimed to. On LiveKit it renders as the prewarmed Silero VADs min_silence_duration instead of an endpointing min_delay that could never fire before the VAD reported end of speech, so every authored value under 0.55s used to be silently inert. Under 250ms is now a compile error, not a first-call crash. Unset stays byte-identical and no golden moved.
  • Warm TTS standby stays, with the claim corrected: it is worth about 40ms of caller-visible time, not the 610ms first reported, plus a real floor improvement from 221ms to 58ms on the best segment. The earlier number was the websocket handshake, which was already off the callers path.
  • Control hops came out of the turn. Verification asks for a phone number only, booking is one task instead of a three-step group, and finish calls in a scripted booking drop from 7 to 2. Tool state moved from SQLite to memory, so get_current_date went from 245ms to 7.7us. llm ttfb over ten samples: 1.212s to 0.895s. Authored prompt text is down 61%.
  • A delegated task no longer answers its parents in-flight call. LiveKit injects the still-running delegate call and a placeholder result into the context the task generates from, so the caller heard an apology for a failure that had not happened. The strip keys on the SDKs own lk_running_placeholder marker. Scripted bookings went from eleven or twelve agent turns to seven.
  • announce: is a new optional scalar on a webhook or local tool file: one fixed sentence the agent speaks as the tool starts. The wait is not the tool, which returns in 1 to 14ms here, it is the second LLM round trip and the TTS after it. Works on both code drivers, including tools listed on a Pipecat task, which a wrong capability claim had refused.
  • docs-site gained a top-level Optimization group and the skill gained references/latency.md, both carrying the seven settings that looked promising and were not, with reasons, so nobody repeats that day.
The SLNG Context Router, fully integrated provider: slng on the think role puts the Context Router in front of your own reasoning model. A repeated turn is answered from cache; a miss goes to the upstream you name, so you keep your model, your provider, and the bill for turns that reach it. Authoring is agent_id, upstream, and params.world_part_override for the regional base URL, over five upstream spellings across openai, openai-compat, azure, vertex and bedrock. On LiveKit it lowers to extra_headers and extra_body on openai.LLM; on Pipecat it merges through OpenAILLMService.Settings.extra. No subclass ships on either. A router-bound system prompt keeps its {{placeholders}} and the values ride alongside in template_variables, so a personalised prompt can still be a cache hit. salon-concierge is now the one place the binding is demonstrated, and it runs in slng_pure_proxy, which keeps every cache write so the cache still warms while nothing is replayed. That is load-bearing rather than belt and braces: the cache key is the (assistant speech, user speech) pair with no system prompt, so two agents in one package can share an entry, and a live call had one agent served anothers line.Also in this release:
  • A locked-down step can hand the caller back instead of refusing. Every task prompt now ends with the compilers own escape, and every generated finish takes a reserved optional unserved_request that the owning agent is told to read.
  • A receiving agent gets its handoffs back after the opening turn. The loop guard used LiveKits IGNORE_ON_ENTER, whose filter leaks into everything the opening reply starts, so one call offered the booking specialist a single tool for ten turns.
  • The pipecat delegate history snapshot is a deep copy, so a history entry that is not a plain dict survives the snapshot and restore round trip.
  • The (pipecat, carrier-websocket, *) routes stop teaching a Pipecat Cloud deploy they have no manifest for, and carry the self-hosted section they were missing.
  • Firecrawl MCP is fully out of both salon examples, gradium STT is in the catalog, and the examples are down to five: four structural packages plus salon-concierge, which keeps the only shipped telephony route.
  • The SLNG marks are replaced with the Unmute brand.
Full notes and downloads
CLI
v0.2.3
Fix for local dev and docs update.Full notes and downloads
CLI
v0.2.2
Hardened orchestration, production-ready examples, and regional deployments.Highlights:
  • Hardens task orchestration across LiveKit and Pipecat, including shared task results, response handling, and session isolation.
  • Strengthens telephony and cold transfers with validated phone routes, call-scoped environment variables, idle-resume handling, and safer local cleanup.
  • Makes Pipecat startup and observability safer with ordered workers, process-safe Langfuse and MCP tracing, and clearer default logging.
  • Adds the full salon concierge example with browser and telephony flows, booking tools, runtime date handling, and release smoke gates.
  • Adds a regional speech infrastructure example and deployment guidance for choosing provider regions.
  • Fixes scaffold environment keys and dotenv loading.
  • Makes the public docs easier to navigate and aligns task, tool, onboarding, and installed-skill guidance.
Included pull requests: #92 to #96 and #98 to #119.Full notes and downloads
CLI
v0.2.1
Upgraded runtimes, verified examples, and clearer docs.Highlights:
  • Upgrades and pins LiveKit Agents 1.6.10 and pipecat-ai 1.7.0, while removing deprecated run modes.
  • Restructures the public documentation into a clearer user journey and corrects CLI, deployment, telephony, secrets, variables, and schema guidance.
  • Makes the CLI easier to use from an agent folder, defaults new packages to LiveKit, and improves phone-route setup guidance.
  • Completes a fresh live sweep of every supported example across browser, outbound, inbound, SIP, Twilio, tasks, handoffs, and transfers.
  • Fixes task-context restoration, repeated delegation, LiveKit handoff loops, outbound call-start variables, LiveKit SIP dispatch authorization, and Pipecat Twilio cold-transfer shutdown.
  • Makes the outbound reminder self-contained and removes the unverified Pipecat Daily transfer example.
Included pull requests: #84, #85, #86, #90, and #91.Full notes and downloads
CLI
v0.2.0
Unmute 0.2.0 makes the first agent run reliable, adds coding-agent support, and opens Windows installation.Highlights
  • Update through Homebrew on macOS or install through Scoop on Windows.
  • Install the bundled coding-agent skill with unmute skill install.
  • LiveKit and Pipecat examples now complete real provider-backed conversations.
  • Agent handoffs are more reliable.
Full notes and downloads
CLI
v0.1.2
brew install slng-ai/tap/unmute works.v0.1.1 published every archive but never pushed the cask. The tap upload was still switched off, and a skipped step does not fail a run, so the release went green with nothing to install. This turns it on.Nothing in the CLI changed. On an archive or a clone of v0.1.1 you are not missing a fix.winget install slng.unmute is still closed and will say so.Full notes and downloads
CLI
v0.1.1
The first release of Unmute, a command line compiler for voice agents.You write a small package of YAML and Markdown that says who the agent is, which models it uses, and which tools it can call. Unmute turns that into a real Python project for the orchestrator you picked. The project it writes is yours: pinned dependencies, a Dockerfile, a runbook, and no dependency on Unmute at runtime. Unmute compiles ahead of time and is never in the call path.What is in this releaseFour commands. init scaffolds a package, validate checks it against its targets and names the file and the line when a field is wrong, compile writes one project per target under build/, and dev compiles, runs the agent locally and lets you talk to it in the browser. Add --console and you talk over the terminal mic and speaker with no Docker in the way. validate prints one status line per target, and every refusal names the fix.Two code targets, one agent. The same package compiles for Pipecat and for LiveKit. Nothing in agent.yaml mentions either one. Where a runtime cannot run a model as defined, targets.yaml overrides that single entry by name and the agent itself does not change.Models named once. Every listen, think, speak and turn model is declared once and referenced by name. Point brain at a different model and every agent using it follows. A provider catalogue turns each binding into code, so the emitted service carries its own import, its dependency pin and its required environment variable, and a provider with no slot on a framework fails by name instead of quietly emitting the wrong class. Pipecat covers anthropic, assemblyai, cartesia, deepgram, deepseek, elevenlabs, google, gradium, groq, inworld, mistral, openai, openrouter, qwen, rime, sarvam, slng, soniox and speechmatics. LiveKit covers the same ground through its native per vendor plugins, plus aws, azure and gemini. An unknown vendor is still legal as a custom OpenAI compatible endpoint, and provider: local runs the Silero turn detector on your own machine.Multi-agent, tasks and task groups. Any number of agents, with agent_transfer between them and history you control per transfer (full, messages, last n, summary or reset). Delegates run a single task or a task group and return where the contract says they return. Task groups can chain, hand over or end. A task can name its own model, so one stage can be cheaper or stronger than the rest of the conversation. Both drivers lower all of this to native primitives: Pipecat Flows on the owning agent, and LiveKit AgentTask sequences with typed session state.Tools, four ways. A webhook tool with bearer or API key auth. A local Python handler in tools/<name>.py, copied in beside the agent. An MCP server as a tool source on both code targets, with optional transport and an optional list of the server tools to offer. And prebuilt tools from the registry, end_call in v1, with an optional closing line. inject adds values to a tool call that the model never sees and cannot overwrite, which is where a user id or a captured slot rides along.Variables and secrets. Typed input variables, usable in templates, injected into tool calls and captured back out of the conversation. secrets lists every environment name the author wrote, and the compiler cross checks the secrets your local handlers actually read. Every *_env field is a name and never a value, so a pasted URL or key fails validation instead of landing in the spec. Seed a variable for a local session with unmute dev --var name=value, the stand in for a real dispatch payload.Telephony. Real phone calls on the routes each platform ships: LiveKit SIP with a Twilio trunk, the LiveKit Twilio connector, the Pipecat carrier WebSocket route, and Pipecat on Daily, either with a Daily number or with your own carrier. unmute dev --telephony runs the resolved route end to end from your laptop: it brings up the routes Compose graph, opens a managed tunnel, points the Twilio webhook at it and writes the local LiveKit SIP trunk records, so a first phone call takes no manual setup. --to places an outbound test call, and --public-url or --no-webhook hand the carrier callback back to you. Local runs need no cloud account, only a carrier account and what runs on your machine.Human transfer. Cold and warm handoffs written as cold: and warm: blocks, with their parameters in the shape block. Each route uses the platforms own primitive and the generated code never owns the audio path: SIP REFER on LiveKit SIP, Dailys room reroute on both Daily number forms, and a carrier markup replacement on the Pipecat carrier stream. Warm transfer lands on LiveKit SIP, with your briefing and the transcript going to the person who picks up. Where a platform has no primitive, validate refuses and names the routes that work. Generated transfer tools log which control fired, and a cold transfer refuses in words when the session is not a phone call.Tracing. A tracing block that lowers to each platforms native integration, with Langfuse examples on both targets.Secrets that match reality. Compiled output carries a .env.example holding exactly the variables that agent needs, and the generated project checks them at startup instead of failing mid call.A runbook per build. Each build/<target>/ gets its own README.md, Dockerfile, compose.dev.yaml, the platform deploy file, and a compile-report.json recording what was resolved, which catalogue entry produced each service and when that entry was last checked against upstream docs.Examples that run. examples/ holds packages that each compile for both targets: salon-support needs nothing but a browser and two keys, twilio-telephony-hello places a real phone call, multi-task, task-groups and subagents cover staged conversations, mcp-example wires an MCP server, and three transfer examples cover the three mechanisms.Getting itOne static binary for darwin, linux and windows, on amd64 and arm64.
Archives are on the release page, each holding the binary, the LICENSE and the README, alongside a signed checksums.txt and one SBOM per archive. unmute --version reports its own commit and build date.MIT licensed.Full notes and downloads
CLI
v0.1.0
One tag push releases unmuteFull notes and downloads