Fallback Skill
Order of precedence
The Fallback Skills all have a priority and will be checked in order from low priority value to high priority value.
If a Fallback Skill can handle the Utterance it will create a response and return True
.
After this no other Fallback Skills are tried. This means the priority for Fallbacks that can handle a broad range of queries should be high (80-100) and Fallbacks that only responds to a very specific range of queries should be higher (20-80). The more specific, the lower the priority value.
Fallback Handlers
Import the FallbackSkill
base class, create a derived class and register the handler with the fallback system
Implement the fallback handler (the method that will be called to potentially handle the Utterance).
The method implements logic to determine if the Utterance can be handled and shall output speech if it can handle the query.
It shall return Boolean True
if the Utterance was handled and Boolean False
if not.
from ovos_workshop.skills.fallback import FallbackSkill
class MeaningFallback(FallbackSkill):
"""
A Fallback skill to answer the question about the
meaning of life, the universe and everything.
"""
def initialize(self):
"""
Registers the fallback handler
"""
self.register_fallback(self.handle_fallback, 10)
# Any other initialize code you like can be placed here
def handle_fallback(self, message):
"""
Answers question about the meaning of life, the universe
and everything.
"""
utterance = message.data.get("utterance")
if 'what' in utterance
and 'meaning' in utterance
and ('life' in utterance
or 'universe' in utterance
or 'everything' in utterance):
self.speak('42')
return True
else:
return False
NOTE: a
FallbackSkill
can register any number of fallback handlers
The above example can be found here.
Decorators
NEW - ovos-core
version 0.0.8
Alternatively, you can use decorators
from ovos_workshop.decorators.fallback_handler import fallback_handler
class MeaningFallback(FallbackSkill):
"""
A Fallback skill to answer the question about the
meaning of life, the universe and everything.
"""
@fallback_handler(priority=10)
def handle_fallback(self, message):
"""
Answers question about the meaning of life, the universe
and everything.
"""
utterance = message.data.get("utterance")
if 'what' in utterance
and 'meaning' in utterance
and ('life' in utterance
or 'universe' in utterance
or 'everything' in utterance):
self.speak('42')
return True
else:
return False
Check utterances
NEW - ovos-core
version 0.0.8
Fallback skills should report if they are able to answer a question, without actually executing any action.
Besides providing performance improvements this allows other OVOS components to check how a utterance will be handled without side effects
def can_answer(self, utterances: List[str], lang: str) -> bool:
"""
Check if the skill can answer the particular question. Override this
method to validate whether a query can possibly be handled. By default,
assumes a skill can answer if it has any registered handlers
@param utterances: list of possible transcriptions to parse
@param lang: BCP-47 language code associated with utterances
@return: True if skill can handle the query
"""
return len(self._fallback_handlers) > 0
Security
Just like with converse a badly designed or malicious skill can hijack the fallback skill loop, while this is not as serious as with converse some protections are also provided
You can configure what skills are allowed to use the fallback mechanism, you can also modify the fallback priority to ensure skills behave well together.
Since priority is defined by developers sometimes the default value is not appropriate and does not fit well with the installed skills collection
"skills": {
// fallback skill configuration
"fallbacks": {
// you can add skill_id: priority to override the developer defined
// priority of those skills, this allows customization
// of unknown intent handling for default_skills + user preferences
"fallback_priorities": {
// "skill_id": 10
},
// fallback skill handling has 3 modes of operations:
// - "accept_all" # default mycroft-core behavior
// - "whitelist" # only call fallback for skills in "fallback_whitelist"
// - "blacklist" # only call fallback for skills NOT in "fallback_blacklist"
"fallback_mode": "accept_all",
"fallback_whitelist": [],
"fallback_blacklist": []
}
},