Corrections (Pattern Extension for Phonetic Matching) [EXPERIMENTAL]¶
Corrections is a matching feature that widens command pattern to accept translation/phonetic variants of known keywords. When STT or user input contains a misspelling or phonetic approximation, this feature injects the variant into the compiled pattern so the command still matches.
Example: user says "tern on the lite" → dictionary contains "turn" and "light" → regex expands "turn" to "(turn|tern)" and "light" to "(light|lite)" → command "turn on the light" matches.
How It Works¶
The feature has three parts:
1. Generation: CorrectionsProcessor¶
A pipeline pre-processor that runs before SearchProcessor. It accepts one or more Dictionary instances and uses their phonetic matching infrastructure (IPA→simplephone→levenshtein with proximity graph) to find corrections.
from stark.core.processors import CorrectionsProcessor, SearchProcessor
from stark.tools.dictionary import build_recognizable_dictionary
from stark.tools.phonetic.transcription import LatinPassthroughProvider
# Build a dictionary from recognizable.strings bundles
dictionary = build_recognizable_dictionary(localizer, ipa_provider=LatinPassthroughProvider())
context = CommandsContext(
...,
processors=[
CorrectionsProcessor(dictionaries=[dictionary]), # generates corrections
SearchProcessor(), # uses them for matching
],
)
When a localizer is provided and no custom processors are specified, CorrectionsProcessor is included automatically in the default pipeline.
The processor accepts any Dictionary instance — not just ones built from recognizable.strings. You can pass custom dictionaries populated with domain-specific vocabulary.
Lookup modes: The processor supports the same modes as Dictionary: EXACT, CONTAINS, FUZZY, and AUTO (default). Pass via CorrectionsProcessor(dictionaries=[...], mode=LookupMode.FUZZY). See Phonetic Dictionary for more details.
Multilingual: For TranscriptionString with alternative tracks, the processor runs dictionary search per each track and stores per-track corrections. See Localization and Multilingual
2. Expansion (automatic)¶
When corrections are present on the input string, PatternParser.match() automatically injects them into the compiled pattern before matching. For each Correction(variant, keyword), if keyword appears as a literal in the compiled regex, it's replaced with (keyword|variant1|variant2|...).
No flag needed despite being an experimental feature — expansion is triggered by the presence of corrections.
3. Back-tracking¶
After a successful match, MatchResult records which corrections were applied:
corrections: dict[str, str]— maps each variant to its keyword (e.g.{"tern": "turn"})corrected_string: str— the matched substring with corrections applied (e.g."turn on the light")
This enables UIs to show the corrected text to the user, and simplifies debugging.
Data Sources¶
Recognizable Strings (built-in)¶
build_recognizable_dictionary() creates a Dictionary from all loaded recognizable.strings bundles. See Localizing Parsing
Custom Dictionaries¶
Any Dictionary instance works — populate it with domain-specific vocabulary:
from stark.tools.dictionary import Dictionary
from stark.tools.dictionary.storage import DictionaryStorageMemory
from stark.tools.dictionary import build_recognizable_dictionary
recognizable_dict = build_recognizable_dictionary(localizer)
custom_dict = Dictionary(storage=DictionaryStorageMemory())
custom_dict.write_one("en", "spotify")
custom_dict.write_one("en", "bluetooth")
processor = CorrectionsProcessor(dictionaries=[recognizable_dict, custom_dict])
IPA Provider Options¶
Dictionary-based matching uses IPA transcription for cross-language phonetic comparison. Available providers.
from stark.tools.phonetic.transcription import LatinPassthroughProvider, EspeakIpaProvider
dict = build_recognizable_dictionary(
localizer,
ipa_provider=LatinPassthroughProvider(fallback=EspeakIpaProvider()),
)
See Phonetic Dictionary and Phonetic Tools for more details and native implementations.
Comparison with NLDictionaryName¶
Both features use Dictionary for phonetic matching, but at different levels:
| Corrections | NLDictionaryName | |
|---|---|---|
| Best for | Fuzzy command keyword matching | Fuzzy named entity parsing |
| Level | Pre-processor + Pattern matching (before parsing) | Parameter parsing (inside did_parse) |
| What it does | Expands patterns with homophones of known words found in the request string | Searches through dictionary programmatically if pattern matched |
| Scope | Scans the entire input string (pre-processing), affects all commands, only expands with homophones present in both the request string and the dictionary | Specific parameter types for commands matched by pattern |
| Data source | All provided Dictionary objects |
Specific Dictionary |
| Cross-language | Yes | Yes |
| Extra requirements | keyword must be present in the compiled pattern as a literal | none, can have "**" pattern |
| Overhead | Longer pre-processing, fast matching | No pre-processing, longer matching |
Corrections are helpful for keywords that are present as literals and can be misheard. NLDictionaryName are designed for extraction of named-entity parameters (names, places, songs). They share the same Dictionary infrastructure as a backend, but apply it differently. Both are in experimental stages, please try both and provide feedback.
See Phonetic Dictionary for Dictionary and NLDictionaryName details, Custom Processors for pipeline setup.