Skip to content

Language Selection and Disambiguation

Maturity: Mature ⬤⬤⬤⬤⬤

Long-lived, well-tested, and actively maintained. This is ovos-core internals. You can depend on it. Rated by repository health, not version.

Just want to change your language?

See Language Support instead. This page covers internals: how ovos-core picks a language for a given utterance internally, not how to configure one.

In a nutshell

Every utterance carries a language tag (on the message context), and ovos-core resolves it from the most trustworthy source available, falling back to your configured default, before it tries to match an intent. If you only ever use one language, the default lang in mycroft.conf is all that matters, and you can skip the details below.

OpenVoiceOS is designed to be multi-language from the ground up. This page explains the technical logic used by ovos-core to determine which language should be used for a given user utterance.

To switch your assistant's language, set lang in mycroft.conf to the new default. To understand a second language as well, without replacing the primary one, list it under secondary_langs. See Make It Yours for the config snippet. Everything below explains how ovos-core picks a language per utterance once those keys are set.

The raw material for that decision is the session's six language signals — lang, secondary_langs, output_lang, stt_lang, request_lang and detected_lang — plus the per-payload data.lang. Each is defined in Session Aware Skills — Language signals.


The Disambiguation Logic

When an ovos.utterance.handle message (legacy: recognizer_loop:utterance) arrives on the messagebus, ovos-core (specifically the IntentService) runs a disambiguation routine to decide which language to use for intent matching.

flowchart TD
    A[ovos.utterance.handle arrives] --> B{context has stt_lang?}
    B -- yes, valid --> V[Use it]
    B -- no / invalid --> C{context has request_lang?}
    C -- yes, valid --> V
    C -- no / invalid --> D{context has detected_lang?}
    D -- yes, valid --> V
    D -- no / invalid --> F[Fall back to configured default lang]
    V --> M[Match intent in resolved language]
    F --> M

Diagram: The flow starts when the utterance message arrives and ends at matching the intent in the resolved language, branching through stt_lang, request_lang, and detected_lang before falling back to the configured default.

"Valid" means the candidate passes against valid_langs via closest_lang (see below). The service inspects the message's context dict and picks the first of these keys that is present and resolves to a valid language:

Priority Context Key Source
1 stt_lang Set by the STT engine that transcribed the speech.
2 request_lang Volunteered by the source (e.g., a per-wake-word stt_lang override — see Wake Word Plugins — or a remote client).
3 detected_lang Set by a Transformer plugin (e.g., a language classifier).

The message language itself is resolved by get_message_lang(), which checks message.data["lang"] first and then message.context["lang"]. If neither is present, it looks for a session on the message (context["session_id"] or context["session"]) and uses that session's lang — in a running system this is the usual source, since each client carries its own session. Only a message with no session at all falls back to the system lang from mycroft.conf.

Validation against valid_langs

Each candidate above is validated against the enabled-language list before it is accepted. That list is taken from message.context["valid_langs"] if the source provided one, otherwise from get_valid_languages() (i.e. lang + secondary_langs in mycroft.conf). OVOS uses the closest_lang helper (from ovos_spec_tools) to find the closest match:

  • If a candidate matches an enabled language within a "distance" of 10 (standard regional difference, e.g. en-auen-us), that enabled language is used.
  • If a candidate does not match, it is skipped (a warning is logged) and the next priority key is tried.

Language Helper Utilities

Developers should use the language helpers from ovos_spec_toolsstandardize_lang() (normalize a tag, e.g. "en-us""en-US") and closest_lang() (pick the closest enabled language). These are what ovos-core itself uses.

Note

The older ovos_utils.lang helpers below (standardize_lang_tag, get_language_dir) are deprecated in favor of the ovos_spec_tools helpers above. They are documented here because existing skills still reference them.

standardize_lang_tag(lang_code, macro=True)

Normalizes a language tag to a canonical form (e.g., "en-us" -> "en-US"). It is used internally to ensure comparisons are reliable. With macro=True it can also collapse a tag to its macro-language.

get_language_dir(base_path, lang="en-US")

An important helper for Skills. It scans a directory (like locale/) and returns the best matching subdirectory for the requested language, tolerating regional variations.


Configuration Helpers

The ovos-config library (ovos_config.locale) provides helpers to retrieve language settings from mycroft.conf.

get_default_lang(config=None)

Returns the primary language tag for the system (the lang key).

get_primary_lang_code(config=None)

Returns just the two-letter primary code (e.g. en) rather than the full BCP-47 tag.

get_valid_languages()

Returns the list of all enabled language tags (lang plus secondary_langs). This is what the Intent Service validates candidate languages against.


Multilingual Intent Matching

If multilingual_matching is enabled under the "intents" section of mycroft.conf, the retry is per pipeline plugin, not a second whole-pipeline pass. For each plugin in priority order, the orchestrator first tries it in the primary disambiguated language. If that plugin declines, it retries the same plugin in every other configured language, and only then advances to the next plugin.

{
  "intents": {
    "multilingual_matching": true
  }
}

This allows switching between languages without manual reconfiguration, at the cost of extra matching work per failed utterance.


Source code: OpenVoiceOS/ovos-core.


Read next: Customizing Language Resources Related: Language Support Overview (incl. switching an install's language) · Sessions (multi-user state) · Intent Service