UniversalSkill¶
In a nutshell
A "Universal" skill is one you write in a single language but that works in many. It automatically translates what the user said into your chosen working language before your code runs. It translates your replies back into the user's language afterward. This lets you handle everything in, say, English while users speak whatever they like. Think of it as a built-in interpreter sitting on either side of your skill. It needs translation plugins set up to work. For the family of skill templates see Skill Classes. For term definitions see the Glossary.
The UniversalSkill class automatically translates input and output messages between different languages.
Use it when native language support is not feasible. It gives you a simple way to handle multilingual interactions.
A
UniversalFallbackclass (ovos_workshop.skills.auto_translatable.UniversalFallback) combinesUniversalSkillwithFallbackSkillfor auto-translating fallback handlers. There is noUniversalCommonQuerySkill— for translated question answering, combine the@common_querydecorator with the translation helpers yourself.
Overview¶
This skill ensures that intent handlers receive utterances in the skill's internal language. Handlers must also produce responses in the same internal language.
The speak method, used for generating spoken responses, automatically translates utterances from the internal language to the original query language.
NOTE: The
self.langattribute reflects the original query language, while received utterances are always inself.internal_language.
Language Plugins¶
To run UniversalSkills you need to configure Translation plugins in mycroft.conf:
// Translation plugins
"language": {
// by default uses public servers
// https://github.com/OpenVoiceOS/ovos-translate-server
"detection_module": "ovos-lang-detector-plugin-server",
"translation_module": "ovos-translate-plugin-server"
},
Latency and missing-plugin behavior
Every incoming utterance and every spoken reply that needs translating adds a round trip
to the configured translation plugin. This can be a remote server call for
ovos-translate-plugin-server, or local model inference for an offline plugin. Plan for
this extra delay before speech starts. If no translation_module (or detection_module)
is configured, or the configured plugin fails to load, self.translator /
self.lang_detector raise the underlying exception the first time they are accessed.
There is no silent fallback to "no translation". The OVOSLangTranslationFactory.create()
call is deliberately left unguarded (ovos_workshop/skills/ovos.py, translator property),
so a missing plugin surfaces loudly instead of silently mistranslating. If you want your
skill to degrade gracefully instead of crashing, wrap the access yourself:
Usage¶
Initialization¶
# Example initialization
from ovos_workshop.skills.auto_translatable import UniversalSkill
class MyMultilingualSkill(UniversalSkill):
"""
Skill that auto translates input/output from any language
This skill is designed to automatically translate input and output messages
between different languages. The intent handlers are ensured to receive
utterances in the skill's internal language, and they are expected to produce
utterances in the same internal language.
The `speak` method will always translate utterances from the internal language
to the original query language (`self.lang`).
NOTE: `self.lang` reflects the original query language, but received utterances
are always in `self.internal_language`.
"""
def __init__(self, *args, **kwargs):
"""
Initialize the UniversalSkill.
Parameters for super():
- internal_language (str): The language in which the skill internally operates.
- translate_tags (bool): Whether to translate the private __tags__ value (adapt entities).
Default True; set False to skip translating that internal
bookkeeping value if your skill doesn't rely on it.
- autodetect (bool): If True, the skill will detect the language of the utterance
and ignore self.lang / Session.lang.
- translate_keys (list): default ["utterance", "utterances"]
Keys added here will have values translated in message.data.
"""
# skill hardcoded in portuguese
super().__init__(internal_language="pt-pt", translate_tags=True,
autodetect=False, translate_keys=["utterance", "utterances"],
*args, **kwargs)
Intents and Utterances¶
Use the register_intent and register_intent_file methods to register intents with universal intent handlers. The usual decorators also work.
The speak method is used to generate spoken responses.
It automatically translates utterances if the output language is different from the skill's internal language or autodetection is enabled.
Universal Intent Handler¶
Info
Users should NOT use the create_universal_handler method manually in skill intents. self.register_intent already calls it for you.
The following example demonstrates its usage with self.add_event.
# Example universal handler creation
def my_event_handler(message):
# Your event handling logic here
pass
# Manual usage with self.add_event
my_handler = self.create_universal_handler(my_event_handler)
self.add_event("my_event", my_handler)
EnglishCatFacts Skill Example¶
This tutorial skill interacts with an API to fetch cat facts in English.
It uses the UniversalSkill class to support translations for other languages.
from ovos_workshop.skills.auto_translatable import UniversalSkill
from ovos_workshop.decorators import intent_handler
class EnglishCatFactsSkill(UniversalSkill):
def __init__(self, *args, **kwargs):
"""
This skill is hardcoded in english, indicated by internal_language
"""
super().__init__(internal_language="en-us", *args, **kwargs)
def fetch_cat_fact(self):
# Your logic to fetch a cat fact from an API
cat_fact = "Cats have five toes on their front paws but only four on their back paws."
return cat_fact
@intent_handler("cat_fact.intent")
def handle_cat_fact_request(self, message):
# Fetch a cat fact in self.internal_language
cat_fact = self.fetch_cat_fact()
# Speak the cat fact, it will be translated to self.lang if needed
self.speak(cat_fact)
In this example, the CatFactsSkill class extends UniversalSkill. This lets it translate cat facts into the user's preferred language.
SpanishDatabase Skill Example¶
This more advanced example is a skill that listens to bus messages.
The skill listens for messages containing a "phrase" payload in message.data. This payload can be in any language. The skill saves this phrase in spanish to a database. Then it speaks a hardcoded spanish utterance. That utterance gets translated into the language of the bus message Session.
from ovos_bus_client.message import Message
from ovos_workshop.skills.auto_translatable import UniversalSkill
class SpanishDatabaseSkill(UniversalSkill):
def __init__(self, *args, **kwargs):
"""
This skill is hardcoded in spanish, indicated by internal_language
"""
translate_keys=["phrase"] # translate "phrase" in message.data
super().__init__(internal_language="es-es",
translate_keys=translate_keys,
*args, **kwargs)
def initialize(self):
# wrap the event into a auto translation layer
handler = self.create_universal_handler(self.handle_entry)
self.add_event("skill.database.add", handler)
def handle_entry(self, message: Message):
phrase = message.data["phrase"] # assured to be in self.internal_language
# Your logic to save phrase to a database
self.speak("agregado a la base de datos") # will be spoken in self.lang
Read next: Testing Skills with ovoscope
Related: OCP Skills · Common Query Framework · Fallback Skill · Skill Classes