Skip to main content
unmute reads one agent.yaml contract. A file written for unmute 0.8 or older has a version: line, and unmute refuses it first:
The current contract is more typed. Each tool’s types come from its Python function. What a tool result saves and says sits on that tool’s entry in agent.yaml, as outcomes:. Handoffs, transfers and flows sit inside the agent that uses them.

Migrate with your coding assistant

Then ask your assistant to migrate the package. The unmute-migrate skill holds the loop and every row below. It runs unmute validate after each change until the package is clean.

Migrate by hand

  1. Read the version: line, then delete it.
  2. If it said version: 1, do From version 1 first.
  3. Do From unmute 0.8.
  4. Run unmute validate . after each change. A retired key’s error names its new spelling, with the file and the line.
  5. Run unmute compile . for every target in targets.yaml.
Move the structure first, because it changes where everything else sits: agents: becomes a list, then handoffs, transfers and flows move inside the agents.

From unmute 0.8

Structure

Renames

A step’s tools

The step keys about one tool move onto that tool’s entry in the step’s tools: list.
agent.yaml

Tool files

What the caller hears and what the call remembers moved from tools/*.yaml to the tool’s entry in the top-level tools: list of agent.yaml.

From version 1

Do these first, then everything under From unmute 0.8. Some rows are from packages older than unmute 0.7. Skip a row the package does not have. A local tool’s types now come from its Python function. Each parameter has a type, a required input has no default, an enum: becomes a Literal[...], and the return type is a Pydantic model:
tools/salon.py
The tool file keeps description:, interruption: and effect:, and its handler is tools/salon.py:find_customer. skip_when_confirmed:, non_blocking:, models:, secrets: and knowledge: are unchanged. A webhook tool keeps input: and output: as JSON Schema. Every key is described in Agent configuration.