Home/Docs/Getting started

Getting started

Five commands, offline, no account. Catch a talk-over on a bundled call, score your own two-channel recording, pin the moment, and gate CI on it. Your audio and traces never leave your machine.

The whole path, in order

Install, then four steps: catch a failure on a bundled call, score your own recording, pin the moment as a contract, and open the pull request that gates CI. Each step below is the exact command. No forks.

1. Install

uvx fetches and runs hotato straight from PyPI with no install step, so every command on this page works as written. For daily use, install it once with pipx, uv, or pip.

bash
# run without installing: uvx fetches hotato on first use
uvx hotato --version

# or install once for daily use
pipx install hotato        # or: uv tool install hotato, or: pip install hotato

2. See it catch a failure

The guided first run sweeps two bundled demo calls (a synthesized talk-over and a recorded provider-default call), ranks the strongest failing moment, freezes it as a portable contract, and re-scores it. It fails by design: the agent talks straight over a caller interruption. The run writes a shareable failure record and prints your next command.

bash
hotato autopsy ./call.wav
hotato start: swept the 2 bundled demo calls offline.
  ------------------------------------------------------------------
Conversation failed: Agent did not yield; measured talk-over was 2.66 s.
  ------------------------------------------------------------------
  Two measured signals on this one call:
    talk-over     2.66s  the agent kept talking while the caller held the floor
    response gap  2.18s  dead air from the caller's turn end to the reply

  Share in a PR:      hotato-failure-record/failure-record.md
  re-scored FAIL, by design: this call talked over the caller. Setup
  finished, so start --demo exits 0. Your next step, score a call:
      hotato autopsy contracts/demo-missed-interruption.hotato/audio/event.wav

3. Score your own call

Point investigate at a two-channel recording. It validates the file, checks it is scorable, and ranks the candidate turn-taking moments, printing the exact command to label each. Swap in your own call; until then, the demo just wrote an event.wav you can run this on.

bash
# a two-channel WAV: caller on channel 0, agent on channel 1
hotato autopsy ./call.wav
hotato autopsy [run 1]: call.wav
  most likely failure (top-ranked candidate):
    [1] t=7.63s agent_stop_no_caller  trailing silence=0.37s
    the agent went quiet for 0.37 s with no caller energy nearby
  turn it into a CI contract (use --expect hold if the agent was right to keep talking):
    hotato investigate label '.hotato/investigate-state.json#1' --expect yield
  input health: eligible for scan
  verdict path: eligible (a labeled event here can carry a yield/hold verdict)
Two channels is the input contract

Separate tracks give every overlap an owner: you see who was already talking and who cut in. A mixed mono file cannot show that, so investigate refuses it (exit 2). If your stack exports one mixed file, switch on separated recording; the capture guides show the setting per stack.

Recording still in your stack? Pull and score it in the same step: hotato investigate --stack vapi --call-id <id>.

4. Pin the catch

Labeling is your decision on the moment: --expect yield means the agent should have stopped for the caller, --expect hold means it was right to keep talking. It writes a portable contract that freezes the moment as evidence and prints the command to open a pull request.

bash
hotato investigate label '.hotato/investigate-state.json#1' --expect yield --id my-first-catch
created hotato contract: my-first-catch
  dir:      contracts/my-first-catch.hotato
  expect:   yield
  scorable: yes
  passed:   False
  measured: did_yield=False seconds_to_yield=n/a talk_over=0.00s
open the pull request that adds it to your repo's CI gate:
  hotato pr create --fixtures contracts/my-first-catch.hotato --repo OWNER/REPO --title 'Add hotato contract my-first-catch'

5. Wire the CI gate

pr create opens a pull request that adds the contract as a regression test with a ready-made GitHub check. The gate command is contract verify: it re-measures the stored evidence and exits non-zero while a pinned call stays red, so a regression fails the build.

bash
# open the PR that adds the contract and the CI check
hotato pr create --fixtures contracts/my-first-catch.hotato --repo OWNER/REPO \
  --title 'Add hotato contract my-first-catch'

# the gate itself: re-score every pinned contract, non-zero on a regression
hotato contract verify contracts/
hotato contract verify: contracts/ (2 contracts)
  [FAIL] demo-missed-interruption (expect yield): talk_over=2.65s | integrity: intact
  [FAIL] my-first-catch (expect yield): talk_over=0.00s | integrity: intact
  0/2 contracts pass; exit_code=1
Exit codes are the gate

0 every contract passes · 1 a pinned failure is still red, the build fails · 2 a usage or input error, including an input that is not scorable. The GitHub Action and the pytest plugin run this same check on every push.

A pinned contract stays red until you fix the agent and recapture the call, the same way a snapshot test stays red until you update the snapshot. contract verify re-measures stored evidence and does not re-run your live agent. hotato prove composes every evidence lane into one fail-closed release proof. When you have a fix, close the loop: recapture and compare before and after → · see the whole loop run against twelve recorded calls →