Configure ParrotFlow with config.yaml

An overview of config.yaml. Where it lives, how to check it, and the main sections for the hotkey, transforms, the pipeline, models and vocabulary.

ParrotFlow reads one file, ~/.config/parrotflow/config.yaml. The app creates it on first launch. Save the file and the app picks up the change at once. You do not need to restart.

This page is an overview. Every key is described in configuration.md on GitHub.

Open and check the file

Open it from the menu bar icon: Settings → Edit Config…. Or open it in any editor.

Check it after every change. --check-config prints what the app will use, and names anything it had to ignore.

parrotflow --check-config

If you installed with the script, use the full path /Applications/ParrotFlow.app/Contents/MacOS/ParrotFlow instead of parrotflow.

To try a pipeline on a sentence without a microphone, write the pipeline in its own YAML file and run --pipeline. It reads that file, not your config. --app sets the app that conditions are matched against.

parrotflow --pipeline my-pipeline.yaml "PR 478 is ready" --app Slack

Both flags are described in cli.md.

The main sections

Section What it sets
hotkey The key you hold to dictate, and push-to-talk or toggle
audio Which microphone to use, and where recordings go
transcription Languages, how text is inserted, the vocabulary pass and the pipeline
transforms Your own rules: patterns, scripts and prompts
lists Named word lists that patterns can reuse
models Language models, local or remote, under names you choose
commands Which model handles each part of “hey parrot, …”
updates How long a release must exist before it is offered
feedback The chime, the pill and its colours
logging What is written to disk about a dictation

A key you leave out takes its default. config.example.yaml in the repository is the file a new install gets.

Hotkey

hotkey:
  key: right_command    # a bare modifier, or a character key + modifiers
  modifiers: []         # required for a character key
  mode: push_to_talk    # or toggle

Bare modifiers are right_option, left_option, right_command, left_command, right_control, left_control, right_shift, left_shift and fn. A character key, such as space or f5, needs at least one modifier. Use push-to-talk with a bare modifier. On toggle, Right Option would start a recording each time you type an accented character.

Full reference: hotkey.

Transcription

transcription:
  languages: [en, fr]   # most spoken first; en and fr are supported
  insert_mode: paste    # or clipboard

languages helps ParrotFlow work out which language a transcript is in. The speech model does not use it. One entry turns language detection off.

insert_mode: paste types the text into the app you are using and needs Accessibility. clipboard copies it and needs no permission. See Permissions.

Transforms

A transform is a rule you write. It has a name, a description and one of three bodies.

transforms:
  - name: github_refs
    description: PR numbers as GitHub links
    replace:
      '[#$1](https://github.com/OWNER/REPO/pull/$1)': ['/\bPR\s*#?(\d+)\b/']

  - name: slack_mentions
    description: turn people's names into Slack mentions
    command: slack_mentions.py

  - name: grammar
    description: fix grammar and punctuation
    prompt: Fix grammar and punctuation. Return only the text.
  • replace: is a substitution table. Keys are what to write. Values are what to match, as plain text or as a regex between slashes. It costs nothing.
  • command: runs your own program. The text arrives on stdin and goes back on stdout. The program runs in the transform’s own folder, ~/.config/parrotflow/transforms/<name>/. If it fails, says nothing or takes longer than two seconds, the text is kept as it arrived.
  • prompt: asks a language model. This is the only kind that needs one.

--check-config lists every command: transform, because that config runs code on your Mac.

Run a transform on demand

Three keys let you run a transform only when you ask for it.

  - name: grammar
    description: fix grammar and punctuation
    offer: true        # a button on the pill after each dictation
    key: g             # press G to run it
    say: [fix grammar] # tap then hold the hotkey, and say it
    prompt: Fix grammar and punctuation. Return only the text.

Full reference: Transforms and Writing a transform.

Pipeline

The pipeline is the list of transforms that run on every dictation, in order.

transcription:
  pipeline:
    - transform: fillers
    - transform: dates_en
    - transform: numbers_en
    - transform: money_en
    - transform: disfluency
    - transform: grammar
      app: /slack|outlook/      # only in Slack and Outlook
    - transform: fillers_fr
      when: language == "fr"    # only for French dictation

To turn a step off, delete its line. when and unless read the text at that point, as a regex between slashes or as an expression. app matches the app you dictate into.

Full reference: pipelines.md, with Conditions and Apps.

Vocabulary

The names and terms you teach ParrotFlow are kept in ~/.config/parrotflow/vocabulary.yaml, beside config.yaml. The app writes that file when you save a correction. See Teach ParrotFlow a word.

The pass that uses it is set in config.yaml. It is on by default and calls no language model.

transcription:
  vocabulary:
    enabled: true
    sound_below: 0.85      # how close a run of words must sound to a term
    gate_sentence: true    # read the sentence before keeping a match
    asks: true             # ask before typing a name it could not settle

Full reference: transcription.vocabulary and corrections.md.

Context spelling

ParrotFlow reads the window you dictate into, on your Mac, when you press the key. It uses the words on screen to spell what you said. For example, it writes CaretAnchor where the speech model heard “carrot anchor”. It is on by default.

transcription:
  context_spelling: {enabled: true}

See Screen context.

Models

You only need a model for prompt: transforms and for “hey parrot, …” commands. Name each model you want to use.

models:
  gemma:               # on your Mac, through Ollama
    api: ollama
    model: gemma4:e4b
    keep_loaded: true
    default: true      # used by any transform that names no model
  gpt:                 # remote
    api: openai
    model: gpt-5.6-luna

api is the protocol: ollama, openai or anthropic. Other providers work through endpoint:. A transform picks a model with model: gpt.

Leave api_key out and the app asks for the key on its next launch and keeps it in your keychain. You can also set it from a terminal. The key is read from stdin, so it stays out of your shell history.

parrotflow --set-key gpt

A remote model sends what you dictate to that provider’s server. If a model call fails for any reason, the transcript is kept as it arrived.

keep_loaded: true keeps an Ollama model in memory. gemma4:e4b then uses 9.6 GB. Turn it off on a 16 GB Mac.

Full reference: models and commands.

Other sections

updates:
  after_days: 0     # 0 offers a release the day it ships; 7 waits a week; -1 never asks

feedback:
  sound: true       # the chime
  overlay: true     # the pill that shows the microphone is on
  theme: system     # or dark, or light

logging:
  text: true        # ~/Library/Logs/ParrotFlow.log
  audio: false      # keep each dictation's recording on disk

For where every file lives, see Install.

More