Skip to content
Version v0.35 ยท supported
[WIP] Pending copyedit and approval.

Recognition and dictation

Amri turns speech into action two ways. Command recognition matches what you say against the fixed set of phrases your profiles define. Dictation transcribes free-form speech into text. Each uses a different engine, and each needs its own model.

Command recognition

Command recognition is the default and fires most commands. Amri builds a fixed grammar from every spoken pattern in your active profiles and the command recognizer matches your speech against that grammar and nothing else. Because the set of allowed phrases is closed, recognition is fast and uses little memory.

When you write a trigger like [walk;move;] forward, it expands into the exact phrases walk forward, move forward, and forward, and those become grammar entries. The recognizer returns one of them or nothing. It does not attempt to transcribe arbitrary speech, which is what keeps command mode responsive.

This is the path behind ordinary triggers: a spoken pattern, matched and dispatched with low latency.

Dictation

Dictation transcribes speech you did not spell out in advance. It is invoked when a command uses a free capture, written with a trailing ...:

[[command]]
name = "search"
description = "Search for a spoken phrase."
lua = "amri.input.text(ctx.captures.query)"
[command.trigger]
pattern = "search for {query...}"

Here the command recognizer matches the fixed prefix search for, and the dictation engine transcribes the tail (nearest coffee shop) and binds it to query. The dictation engine gives higher accuracy on unconstrained speech at the cost of higher latency, so a free-capture command fires a moment after you stop speaking rather than instantly. See free-text dictation for how a capture opens, closes, and dispatches.

Dictation is slower than command mode

A free capture holds its place in order: commands spoken after it wait until its transcription finishes, so everything runs in the order you spoke. This is inherent to free-text transcription, not a fault.

Models

Recognition and dictation each load a model at startup.

Model Used by Source
Command model Command recognition Ships bundled with Amri.
Dictation model Dictation / free captures Resolves to a bundled default (ggml-base.en.bin) beside the binary, or a path you set.

The command model is always present. The shipping build also bundles the dictation model, so dictation works without any setup. Dictation is a core feature, not an opt-in: if no model resolves, the daemon does not start and reports where it looked, the same way a missing command model is treated. To use your own dictation model, set an explicit path:

[dictation]
model = "/path/to/ggml-base.en.bin"
silence_timeout_ms = 800
max_window_ms = 30000
Key Effect
model Path to the dictation model. Empty resolves the bundled default.
silence_timeout_ms Trailing silence that closes a dictation window. Default 800.
max_window_ms Hard cap on one dictation window. Default 30000.

These keys live under [dictation] in engine.toml. For free-capture timing knobs and recognition thresholds, see tuning; for how Amri decides when to listen at all, see listening modes.