1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
# talk-rs Configuration File
#
# This file contains all required settings for talk-rs operation.
# Replace all <PLACEHOLDER> values with your actual configuration.
#
# For more information, see: https://github.com/talk-rs/talk-rs
# Required: Output directory for recordings, screenshots, and clipboard saves.
# The `record` command saves recordings here by default (memo-YYYY-MM-DD-HH-MM-SS.ogg).
# Must be an absolute path that is writable. A leading `~` (or `~/`)
# is expanded to your home directory.
output_dir: <PLACEHOLDER>
# Optional: Recording quality for the `record` command's .ogg output.
#
# These settings control the quality of recordings meant for a HUMAN
# to listen to / share. They are independent of transcription: audio
# sent to the transcription providers is always downsampled to 16 kHz
# mono internally (both Voxtral and Whisper operate at 16 kHz), so
# these knobs do NOT affect transcription accuracy or upload size.
#
# Defaults (used when this section is omitted): 48 kHz, mono, 128 kbps.
# Also overridable via TALK_RS_RECORDING_SAMPLE_RATE /
# TALK_RS_RECORDING_CHANNELS / TALK_RS_RECORDING_BITRATE env vars.
# recording:
# sample_rate: 48000 # Hz (48000 = full-band, no resampling)
# channels: 1 # 1 = mono (recommended for voice), 2 = stereo
# bitrate: 128000 # bps (Opus; 128 kbps is transparent for voice)
# Required: Transcription Providers Configuration
# Configure at least one provider (Mistral or OpenAI)
providers:
# Mistral API Configuration
mistral:
# Your Mistral API key for authentication
# Get this from: https://console.mistral.ai/
api_key: <PLACEHOLDER>
# Base URL for the Mistral API (optional, defaults to "https://api.mistral.ai")
# Override to point at a self-hosted or API-compatible endpoint.
# Only the base URL — path segments are appended automatically.
# url: https://api.mistral.ai
# Model name for transcription (optional, defaults to "voxtral-mini-2507")
# Available models: voxtral-mini-2507, voxtral-mini-2602, voxtral-mini-latest
# V2 models (2602+) support speaker diarization via --diarize
# model: voxtral-mini-2507
# Context bias: comma-separated words/phrases to improve transcription accuracy
# Up to 100 words. Useful for proper nouns, technical terms, domain vocabulary.
# Optimized for English; experimental for other languages.
# context_bias: "Kalysto,talk-rs,Voxtral,cpal,tokio"
# Text-to-speech (used by the `speak` command with --provider mistral).
# The API key above is SHARED between speech-to-text and text-to-speech;
# there is no separate voxtral section.
#
# Model for the /v1/audio/speech endpoint (optional, defaults to
# "voxtral-mini-tts-latest").
# tts_model: voxtral-mini-tts-latest
#
# Default preset voice id (a Mistral voice UUID) used when --voice is not
# given. List available voices with GET /v1/audio/voices?voice_type=preset.
# tts_voice: "5a271406-039d-46fe-835b-fbbb00eaf08d" # Marie (fr_FR)
# OpenAI API Configuration (optional)
# openai:
# api_key: <PLACEHOLDER>
# url: https://api.openai.com # base URL (optional, for compatible endpoints)
# model: gpt-transcribe # batch default
# realtime_model: gpt-live-transcribe # realtime WebSocket default
#
# # Optional migration hints. Omit any field you do not need.
# prompt: "Preserve punctuation and spell product names exactly."
# keywords: [Kalysto, talk-rs] # gpt-transcribe / gpt-live-transcribe
# languages: [fr, en] # expected languages, ordered by preference
# realtime_delay: low # minimal | low | medium | high | xhigh
#
# New defaults and legacy capabilities:
# - gpt-transcribe (batch) sends prompt, repeated keywords[], repeated
# languages[], and response_format=json.
# - gpt-live-transcribe (realtime) sends prompt, keywords, languages, and
# delay under session.audio.input.transcription.
# - whisper-1 remains available for segment/word timestamps, subtitles,
# and translation workflows. It accepts prompt and one singular language,
# uses response_format=verbose_json, but not keywords or multiple languages.
# - gpt-4o-transcribe and gpt-4o-mini-transcribe remain batch choices.
# - gpt-realtime-whisper remains a realtime choice; it accepts prompt and one
# singular language, but not keywords, multiple languages, or realtime_delay.
# Incompatible configured hints fail locally before HTTP/WebSocket traffic;
# they are never silently dropped. There is no structured previous-turn field:
# earlier-turn context is managed by the OpenAI service where supported.
#
# Environment overrides use the same field names:
# TALK_RS_PROVIDERS_OPENAI_PROMPT, TALK_RS_PROVIDERS_OPENAI_KEYWORDS,
# TALK_RS_PROVIDERS_OPENAI_LANGUAGES, TALK_RS_PROVIDERS_OPENAI_REALTIME_DELAY.
# KEYWORDS and LANGUAGES are comma-separated; whitespace is trimmed and empty
# entries are ignored (for example: "Kalysto, talk-rs" and "fr, en").
#
# Direct-OpenAI prices checked 2026-07-31:
# gpt-transcribe $0.0045/min ($0.27/hr); whisper-1 $0.006/min ($0.36/hr).
# gpt-transcribe is 25% lower, saving $0.09 per hour.
# Parakeet local backend (on-device, offline, CPU). No API key.
# NVIDIA Parakeet TDT 0.6b v3, 25 European languages incl. French.
# The model (~640 MB INT8) auto-downloads on first use into
# ~/.local/share/talk-rs/models/parakeet-tdt-0.6b-v3-int8/ and is
# cached forever after (fully offline thereafter).
# Requires the `parakeet` build feature (enabled by default; drop
# via `cargo build --release --no-default-features`).
# parakeet:
# variant: int8 # int8 (default, ~640 MB) — fp32 not yet available as a prebuilt download
# # model_dir: ~/.local/share/talk-rs/models/parakeet-tdt-0.6b-v3-int8 # override cache location
# num_threads: 2 # decode threads (default 2)
# # model: parakeet-tdt-0.6b-v3-int8 # logical name surfaced in cache keys / metadata
# Kokoro local TTS backend (on-device, offline, CPU). No API key.
# Multi-language text-to-speech used by the `speak` command with
# --provider kokoro. The model (~350 MB) auto-downloads on first use
# into ~/.local/share/talk-rs/models/kokoro-multi-lang-v1_0/ and is
# cached forever after (fully offline thereafter).
# Requires the `kokoro` build feature (enabled by default; drop via
# `cargo build --release --no-default-features`).
#
# Language handling is config-driven and agnostic: the requested
# language (--lang / lang below) selects the phonemizer. The stock
# model ships one baked language (en-us); other languages are derived
# on demand by patching the model's ONNX voice metadata, cached as
# model-<lang>.onnx next to the stock model.
# kokoro:
# # model_dir: ~/.local/share/talk-rs/models/kokoro-multi-lang-v1_0 # override cache location
# voice: af_heart # default voice name (af_heart, am_michael, ff_siwis, …)
# num_threads: 4 # inference threads (default 4)
# lang: en # default phonemization language (en, fr, …)
# Optional: Default provider when --provider is not specified.
# Valid values: mistral, openai, parakeet.
# transcription:
# default_provider: mistral
# Optional: Default text-to-speech provider for the `speak` command,
# used when --provider is not specified. Valid values: kokoro, mistral.
# When omitted, `speak` prefers the local Kokoro backend if a
# providers.kokoro section exists, else falls back to Mistral.
# speak:
# default_provider: kokoro
# Optional: Visual and Audio Indicators
# Configure feedback mechanisms during recording
indicators:
# Interval between boop sounds in milliseconds
# Set to 0 to disable audio feedback
boop_interval_ms: 5000
# Show visual indicator overlay during recording
# Set to false to disable visual feedback
visual_overlay: true
# In-badge audio visualizer during recording (disabled by default).
# Available modes: waterfall, amplitude, spectrum
# Also settable via --viz <MODE> or TALK_RS_INDICATORS_VIZ env var.
# viz: waterfall
# Monochrome visualizer (theme-aware: white on dark, black on light).
# Also settable via --mono or TALK_RS_INDICATORS_MONO env var.
# mono: false
# Optional: Paste Behaviour
# Configure how transcribed text is pasted into the target application.
#
# Omitting `paste:` entirely reproduces the default: chunk text at 150
# characters, then paste each chunk via Ctrl+Shift+V (clipboard).
#
# Two schemas are accepted:
#
# ── SCHEMA 1: LEGACY FLAT (still fully supported) ────────────────────────────
#
# paste:
# # Maximum characters per clipboard paste chunk (default: 150).
# # Text longer than this is split on word boundaries into consecutive
# # paste keystrokes. Keeping chunks small avoids terminal paste-summary
# # collapse. Set to 0 to disable chunking. Also --no-chunk-paste.
# chunk_chars: 150
#
# # Paste shortcut sent after loading the clipboard (default: ctrl_shift_v).
# # Use ctrl_v for terminals that don't support Ctrl+Shift+V.
# shortcut: ctrl_shift_v # or: ctrl_v
#
# # Milliseconds to wait for the TARGET WINDOW to actually fetch each
# # clipboard chunk before retrying or aborting (default: 500).
# # This is a per-attempt deadline: if the target doesn't fetch within
# # this window, talk-rs re-focuses the target window and re-sends the
# # paste keystroke (up to target_fetch_retries additional attempts).
# # After all retries are exhausted the paste aborts with a red overlay
# # and alert sound, and your original clipboard is restored.
# # Total effective wait before abort = chunk_fetch_timeout_ms × (1 + target_fetch_retries).
# # The wait short-circuits as soon as the fetch lands, so a higher
# # value costs nothing in the common case.
# chunk_fetch_timeout_ms: 500
#
# # Number of automatic retries when the target app doesn't fetch a
# # chunk within chunk_fetch_timeout_ms (default: 2). On each retry,
# # talk-rs re-focuses the target window and re-sends the paste
# # keystroke. After all retries are exhausted the paste aborts with
# # a red overlay + alert sound, and your original clipboard is restored.
# target_fetch_retries: 2
#
# # Quiet-window in ms used to learn how many times the target fetches
# # each chunk (default: 50). After the first fetch, talk-rs waits
# # this long for additional fetches before declaring the count stable.
# # Subsequent chunks must reach the same count before advancing.
# target_quiescence_ms: 50
#
# # DEPRECATED / no-op. Accepted for backward compatibility but has
# # no effect. The old settle-loop heuristic was replaced by
# # target-confirmation (see chunk_fetch_timeout_ms above).
# # restore_settle_ms: 200
#
# ── SCHEMA 2: NEW TREE (composable node tree) ────────────────────────────────
#
# The tree schema lets you route paste behaviour per display server and
# per target application. Each node has a `node:` key that selects its
# type. Nodes are composable: most accept a `child:` (or `children:`)
# that is itself a node.
#
# Available node types:
# detect-display-server -- routes by $WAYLAND_DISPLAY (x11 / wayland branch)
# match-wm-class -- first-match routing on "<instance>.<class>" glob
# chunk -- splits text into word-boundary chunks, delegates each
# clipboard -- sets clipboard + sends paste shortcut, waits for target fetch
# xtest-type -- types text via XTest synthetic keystrokes (no clipboard;
# ASCII/Latin-1 only; non-Latin-1 chars skipped with a warning)
#
# Full example (uncomment and adjust to taste):
#
# paste:
# node: detect-display-server
# x11:
# node: match-wm-class
# patterns:
# # Terminals: type directly via XTest (no clipboard needed)
# - match: "*.Alacritty"
# child:
# node: xtest-type
# # Terminals using Ctrl+Shift+V (most VTE-based terminals)
# - match: "*.gnome-terminal-server"
# child:
# node: clipboard
# shortcut: ctrl_shift_v
# chunk_fetch_timeout_ms: 500
# target_fetch_retries: 2
# target_quiescence_ms: 50
# # Emacs: uses Ctrl+Y (yank); no chunking needed
# - match: "emacs.*"
# child:
# node: clipboard
# shortcut: ctrl_v
# chunk_fetch_timeout_ms: 500
# target_fetch_retries: 2
# target_quiescence_ms: 50
# # Firefox and most GUI apps: chunk then paste via Ctrl+Shift+V
# - match: "*.firefox"
# child:
# node: chunk
# chunk_chars: 150
# child:
# node: clipboard
# shortcut: ctrl_shift_v
# chunk_fetch_timeout_ms: 500
# target_fetch_retries: 2
# target_quiescence_ms: 50
# # Default for any window not matched above
# default:
# node: chunk
# chunk_chars: 150
# child:
# node: clipboard
# shortcut: ctrl_shift_v
# chunk_fetch_timeout_ms: 500
# target_fetch_retries: 2
# target_quiescence_ms: 50
# # wayland: currently errors ("Wayland paste not supported"); X11 only for now.
# Optional: Runtime Audio Settings
# audio:
# # Auto-switch a connected Bluetooth headset to its Hands-Free
# # Profile (HFP) for the duration of a recording so the headset
# # microphone is enabled, then restore the original profile
# # (typically A2DP) on stop. Default: true. Override per-invocation
# # with --no-bt-auto-switch, or globally via the
# # TALK_RS_AUDIO_BT_AUTO_SWITCH env var (true/false/yes/no/1/0/on/off).
# bt_auto_switch: true