Customizing Language Resources¶
In a nutshell
Every skill ships small text files that say what phrases to listen for and what to say back. This page shows how to swap in your own versions of those files, to reword a reply, fix wording for your accent or dialect, or add a language a skill doesn't include, all without editing the skill's actual code. You drop your edited copy into a personal folder, and OVOS loads yours instead, falling back to the skill's original for anything you didn't change. See Language Support for the bigger picture, or the Glossary for terms.
OpenVoiceOS lets you override or extend a skill's locale resources, the plain-text files that tell the assistant what to listen for and what to say, without touching the skill's source code. This is how you localize responses, fix intent matching for your accent, reword a reply, or add a language a skill doesn't ship.
New here? A skill ships small text files grouped by language. You can drop your own copy of any one of those files into a user folder, and OVOS loads yours instead of the skill's. You only override the files you care about. Everything else falls back to the skill.
π Formal specification
Locale resource layout and file formats are defined by OVOS-INTENT-2: Locale Resource Formats (companion to OVOS-INTENT-1, the sentence-template grammar). See the spec index. This page describes how OVOS implements that spec. The spec is the normative reference.
Resource Roles¶
Per OVOS-INTENT-2, every resource is identified by a (role, base name) pair, where the role is the file extension. There are five roles:
| Role | Extension | Slots? | Purpose |
|---|---|---|---|
| Intent | .intent |
yes (slot-bearing) | Templates matched against the user's speech (ASR input). Slots are filled by the engine at match time. |
| Dialog | .dialog |
yes (slot-bearing) | Phrases the assistant speaks back (TTS output). Slots are filled by the skill before speaking. |
| Entity | .entity |
no (slot-free) | Example values that can fill a named slot. |
| Vocabulary | .voc |
no (slot-free) | A named set of localized phrasings. |
| Blacklist | .blacklist |
no (slot-free) | Words that suppress an intent. |
Two files may share a base name only if their roles differ (confirm.intent and confirm.dialog are distinct resources). Two files with the same extension must not share a base name anywhere in one language's directory tree.
Locale Folder Layout¶
All localized resources live under a single locale/ directory, with one subdirectory per language, named with a BCP-47 tag. This is case-insensitive: en-US and en-us are the same:
my-skill/
βββ locale/
βββ en-US/
β βββ turn_on.intent
β βββ confirm.dialog
β βββ device.entity
β βββ thing.voc
β βββ dialogs/ # subdirectories are allowedβ¦
β βββ greeting.dialog # β¦and searched recursively
βββ pt-BR/
βββ β¦
A language directory may contain subdirectories. A loader resolves a resource by searching the language directory and all its subdirectories recursively. Subdirectory names are an authoring convenience and carry no meaning to the loader.
Legacy layouts
Older skills used vocab/<lang>/ and dialog/<lang>/ directories instead of locale/<lang>/. OVOS still searches these for backwards compatibility, but new skills and overrides should use locale/.
Resolution Precedence¶
The same resource, the same (role, base name) pair, may exist in three places. OVOS
resolves it in this order (first match wins):
- User overrides:
<xdg_data>/resources/<skill_id>/locale/<lang>/ - Skill resources: the skill's own bundled
locale/<lang>/ - Core resources: fallback files shipped by the framework (e.g.
ovos-workshop)
Overrides apply at whole-file granularity: an override file replaces the corresponding lower-precedence file entirely. You do not merge line-by-line, and you do not need to copy files you aren't changing.
.dialog files are honored by the user-override tier since ovos-workshop 9.5.3a1,
the same as .intent, .voc, .entity, .rx (regex), and the other resource roles. The
override only takes effect if the user directory already exists when the skill loads.
Where the user override folder lives¶
The user override base is <xdg_data>/resources/<skill_id>/, where <xdg_data> is the XDG
data path, by default ~/.local/share/mycroft. A typical override file path is:
How to Override¶
- Find the skill ID, e.g.
ovos-skill-weather.openvoiceos. - Create the folders:
~/.local/share/mycroft/resources/<skill_id>/locale/<lang>/. - Copy and edit: copy the
.dialog,.intent,.voc,.entity, or.blacklistfile you want to change from the skill's source into that folder and edit it. - Restart
ovos-coreto pick up the change.
Partial overrides
Only place the specific files you want to change. The loader falls back to the skill (and then core) resources for everything you didn't override.
Language fallback¶
If the requested language has no directory, the loader prefers an exact match but may fall
back to the nearest available language. OVOS resolves this through ovos-spec-tools' language-matching helpers (lang_matches/lang_distance, built on langcodes) and
treats a distance of 10 or less as a usable regional match (the bound is inclusive β
10 is exactly the distance of a language against its macrolanguage tag), e.g. en-au
resolving to en-us.
Per the spec this fallback is an implementation choice, not a guarantee. Ship the exact
language directory you need.
File Format Basics¶
All five roles are line-oriented UTF-8 text (OVOS-INTENT-2 Β§3):
- one template per line;
- blank lines and lines beginning with
#(comments) are skipped; - both
LFandCRLFline endings are accepted.
Slot-bearing files (.intent, .dialog) use the OVOS-INTENT-1 sentence-template grammar:
expansion (a|b), optional [x], and named slots {name}. Slot-free files (.entity,
.voc, .blacklist) use expansion only, with no {slots}.
Two slots must never sit next to each other with nothing between them: {r} {g} {b} raises
MalformedTemplate at registration because there is no way to tell where one slot's match
ends and the next begins. Put a literal word between them instead, for example
{r} and {g} and {b}.
System-wide Resource Overrides¶
Some core, non-skill resources (sounds, common error/boot dialogs) are resolved by the
framework outside the per-skill scheme above. Custom .wav sounds and core .dialog files
placed in the framework's resource locations let you change the assistant's "personality".
These paths are framework-defined. Only the locale/<lang>/ layout beneath a resource root
is normative.
Customizing Number, Date, and Language-Name Parsers¶
The technical parsers for numbers, dates, and spoken language names are separate libraries, not skill resources:
- Language names:
ovos-lang-parsermaps BCP-47 codes to spoken names. - Numbers:
ovos-number-parser(e.g. if "22nd" doesn't parse in your language). - Dates:
ovos-date-parser.
These are rule-driven per language. Contribute fixes upstream to the respective repository so
every install benefits. Local edits to an installed package do not persist across upgrades.
Each language gets its own module, named numbers_<code>.py in ovos-number-parser
(for example numbers_pt.py) and dates_<code>.py in ovos-date-parser
(for example dates_pt.py); adding one is how you give a new language cardinal/ordinal
pronunciation, number extraction, or date/time parsing instead of falling back to the generic
implementation. See Adding a New Language for the
full path from a missing language to a released one.
Read next: Bidirectional Translation Related: Language Selection Β· Resource Files Β· Language Support Overview (incl. switching an install's language)