Skip to main content

Voice

Voice adds speaking as an input method to TF Code. Talk to the agent instead of typing: the mic captures audio, TF Code transcribes it through the ToothFairyAI media API and the transcript lands in the prompt box — with auto-send, it goes straight to the agent after a clear pause. The experience includes an always-on, hands-free mode — the mic stays on and a local voice detector (running entirely on your machine, no server round-trips) fires transcription on speech, so you never click record/stop.

Two extras close the loop:

  • Spoken agent callouts — during long tasks, the agent can call a voice_update tool to speak short, high-signal updates or questions out loud. Voice is an attention channel: full detail stays in the transcript/UI.
  • Speak responses — play any assistant response as speech, with your pick of voice (male/female/character) and language, powered by Cartesia Sonic behind the scenes.
note

Voice transcription and speech generation use the same ToothFairyAI media API as the rest of the workspace (regional endpoints per your profile — au, eu, us). Transcription uses Whisper Large V3 Turbo; a warm request transcribes a short spoken clip in under a second.

Requirements

PlatformHands-free capture (TUI)Fallback recorder (TUI)Playback of spoken calloutsOS permissions
Webbrowser mic + Web Audio (no local tools needed)browser audiobrowser microphone permission (prompted on first use)
macOSsox (brew install sox)ffmpegbuilt-in afplayMicrophone granted to the terminal/app running tfcode
Linuxsox (sudo apt install sox)arecord / parecord / ffmpegffplay (sudo apt install ffmpeg)Linux audio access (ALSA/Pulse)
WindowsTUI capture not supported yet (web works)

The web client needs none of these tools — everything (voice detection, recording, playback) runs in the browser. The tool checklist exists to unlock the richer terminal (TUI) experience.

First-time setup

Probe and prepare the machine in one step — this checks audio tools, runs a short capture that triggers the macOS microphone permission dialog, and prints the exact install command for anything missing:

tfcode voice setup

Pass --install to run the suggested install automatically — brew needs no sudo on macOS; on Linux sudo will prompt for your password:

tfcode voice setup --install

Then verify:

tfcode voice doctor
tip

On macOS, the setup probes the microphone, which triggers the OS permission dialog so you can click Allow right away. Like all TCC permissions, it can't be pre-granted — it's a one-time click in System Settings → Privacy & Security → Microphone.

Enabling

Voice is off by default. Enable it per session — the mic button, settings, and the model's voice_update tool only appear when it is on.

Web & Desktop app

Click the microphone icon in the prompt toolbar, or press Ctrl+Alt+V. If terminal voice tools are missing, a setup dialog opens (you can install them with one click there) — but since web voice always works, you can enable straight away. The toggle persists across reloads.

When enabled, click the mic button to start a hands-free session: the wave animation switches between Listening (calm, dimmed), Speaking · Ns (active), and Transcribing (shimmer) as the local detector picks your voice up. Say something — a short pause ends the utterance, the transcript is inserted at the cursor, and the session re-arms for the next sentence. Click again to end the session.

With auto-send on by default (Settings → Voice), a transcript that reads complete is sent automatically after a short, clear pause in speech — say your message, stop talking, and it goes. A deliberate buffer of silence confirms the pause before anything is sent: if you start speaking again within it, the send is cancelled and your prompt keeps building. Mid-thought pauses are detected via sentence punctuation (in every supported language) and merge continuations into one message, so "add a …" doesn't fire before you finish the request. Turn it off if you prefer transcripts to land in the box for review.

TUI

Run the command picker (e.g. Ctrl+P) and choose:

voice.toggle — enable/disable voice for the session (pre-flights tools)
voice.record — hands-free voice input (sox)
voice.record.push— push-to-talk voice input
voice.speak — speak the last assistant response

While hands-free is armed, a ◉ live chip appears in the prompt footer; the chip turns ● rec while an utterance is being spoken/recorded.

You can bind a key for it. Add the keybind in tui.json under keybinds (it defaults to none, so it is command-only out of the box):

{
"keybinds": {
"voice_toggle": "ctrl+alt+v"
}
}

See Commands for all slash commands and shortcuts.

Server mode & non-interactive runs

OPENCODE_ENABLE_VOICE=true tfcode serve

This turns voice capabilities on for every session in the process — the spoken-callout tool and the corresponding system-prompt guidance appear for all agents.

How it works

Voice input (speech-to-text)

  1. Talk — audio is captured to the browser (Web) or a native recorder (TUI).
  2. Local detection — hands-free mode uses an energy-based voice activity detector running locally (Web Audio analyser): ~120ms of continuous voice arms capture, and ~700ms of trailing silence closes the utterance. Nothing leaves your machine until actual speech is captured.
  3. Transcribe — the captured clip streams straight to the ToothFairyAI media API's transcription endpoint (Groq Whisper Large V3 Turbo). No intermediate storage round-trips — tuned for push-to-talk latency.
  4. Queue, never drop — if you start talking while a transcription is still running, the speech is captured on a fresh recorder and queued; transcripts are applied in order, so rapid-fire instructions aggregate into the prompt instead of being lost.
  5. Insert & send — the transcript is placed at the cursor. With auto-send on (the default), messages that read complete are sent automatically after a clear silence buffer (see below); otherwise they wait for review.

Push-to-talk (voice.record.push) skips detection entirely: one command starts recording, running it again stops and transcribes.

Spoken agent callouts (voice_update)

When voice is on, agents get a voice_update tool for short, high-signal voice callouts during long tasks — a milestone ("database migration done"), a blocker, or a question. The tool's description enforces the discipline: one short sentence (≤ ~15 words), no jargon, no file paths, nothing the UI already shows. A per-session cooldown (15s) prevents spam, and repeated calls are silently suppressed. Subagents can be silenced per-agent via Permissions by denying the voice_update tool.

Voice conversations get spoken answers. The agent is told when a message was spoken (dictated hands-free) — and when a spoken message is conversational (a question, a discussion, ideas, anything chat-like that doesn't need tool work), the agent speaks at least the core of its answer (kind answer, which bypasses the cooldown) alongside the full text reply. You never have to stop and read a response to something you said. Task-style turns (analysis, edits, long tool runs) stay text-first with milestone callouts.

Speak responses

Run the Speak last response action (web/desktop) to convert the latest assistant message into speech and play it with the platform player (afplay on macOS, ffplay on Linux). The agent's own callouts stream to every connected frontend the same way and are played automatically.

Voice settings

Settings → Desktop → General → Voice:

SettingDescription
LanguageVoice language — filters the available voices (English, Spanish, French, …)
VoicePick a voice, with gender shown (e.g. "Helpful Woman (Female) – American ⚡")
Auto-sendSend transcribed messages automatically after a clear pause (default on). Mid-thought pauses merge continuations into one message. Turn off to keep transcripts in the box for review.

The TTS engine is Cartesia Sonic, chosen behind the scenes, so the full multilingual voice catalog is available without a model picker. The picked voice is used for spoken responses and the agent's callouts. In the TUI, set voice_id and voice_language in the TUI state store (or leave default).

Transcription language can be hinted per utterance with voice_language (an ISO 639-1 code).

Configuration

Perks (session defaults)

Perks are named capabilities the user enables on demand, whose default on/off state applies to every new session. tfcode.json:

{
"perks": {
"computer-use": true,
"voice": true
}
}

When perks.voice is set, every new session starts with the voice toggle in that state; you can still toggle it per session. Absent perks default to off. See Config.

Environment variables

VariableDefaultDescription
OPENCODE_ENABLE_VOICEunset (off)Enable voice capabilities process-wide for all sessions

This is the headless/CLI parity switch with OPENCODE_ENABLE_COMPUTER_USE. For interactive use the UI toggles are enough.

Permission key

Control the voice_update tool with the voice_update permission key per agent:

{
"agent": {
"build": {
"permission": {
"voice_update": "allow"
}
}
}
}

Set "deny" to silence an agent (useful for subagents). See Permissions.

Troubleshooting

Run the doctor first — it pinpoints what's missing:

tfcode voice doctor

macOS — sox not found: install it. Hands-free voice capture relies on sox's silence detection; ffmpeg suffices for push-to-talk only. The web client and the setup dialog can install it for you (Install tools), or:

brew install sox
# or automatically:
tfcode voice setup --install

macOS — Microphone denied: grant the permission to the terminal or app running tfcode in System Settings → Privacy & Security → Microphone. tfcode voice setup re-probes and reports it as ✗ until granted.

Linux — tools missing: install the stack.

sudo apt install sox ffmpeg

Web — transcription fails: check the browser microphone permission (site must be allowed), and that your workspace has API access configured (connected profile / TF_API_KEY).

Hands-free keeps missing the start of words, or random triggers: the local detector runs on configurable thresholds. In noisy spaces (open plan, music) raise the threshold, or fall back to push-to-talk. When agents speak back through your speakers, browser echo cancellation handles most overlap — if their voice re-triggers the mic, lower your speaker volume or use headset.

Transcription is slow once after a deploy: the first request pays a one-time server-side cold start (up to ~20s). Subsequent calls are typically ~0.3–0.6s upstream.

No sound when speaking responses (TUI/Linux): playback uses afplay (macOS, built-in) or ffplay (Linux, ships with ffmpeg).

See also Troubleshooting.