Skip to content

Commit

Permalink
Merge pull request #569 from OpenVoiceOS/release-0.2.4a1
Browse files Browse the repository at this point in the history
Release 0.2.4a1
  • Loading branch information
JarbasAl authored Oct 16, 2024
2 parents f704fbf + 8e82b76 commit 9680cb4
Show file tree
Hide file tree
Showing 25 changed files with 166 additions and 153 deletions.
14 changes: 3 additions & 11 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,12 @@
# Changelog

## [0.2.3a1](https://github.com/OpenVoiceOS/ovos-core/tree/0.2.3a1) (2024-10-15)
## [0.2.4a1](https://github.com/OpenVoiceOS/ovos-core/tree/0.2.4a1) (2024-10-16)

[Full Changelog](https://github.com/OpenVoiceOS/ovos-core/compare/0.2.2a1...0.2.3a1)
[Full Changelog](https://github.com/OpenVoiceOS/ovos-core/compare/0.2.3...0.2.4a1)

**Merged pull requests:**

- fix:log\_spam [\#566](https://github.com/OpenVoiceOS/ovos-core/pull/566) ([JarbasAl](https://github.com/JarbasAl))

## [0.2.2a1](https://github.com/OpenVoiceOS/ovos-core/tree/0.2.2a1) (2024-10-15)

[Full Changelog](https://github.com/OpenVoiceOS/ovos-core/compare/0.2.1...0.2.2a1)

**Merged pull requests:**

- deprecate ready setting [\#554](https://github.com/OpenVoiceOS/ovos-core/pull/554) ([JarbasAl](https://github.com/JarbasAl))
- fix:standardize\_lang [\#568](https://github.com/OpenVoiceOS/ovos-core/pull/568) ([JarbasAl](https://github.com/JarbasAl))



Expand Down
2 changes: 2 additions & 0 deletions ovos_core/intent_services/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from ovos_core.intent_services.stop_service import StopService
from ovos_core.transformers import MetadataTransformersService, UtteranceTransformersService
from ovos_plugin_manager.templates.pipeline import IntentMatch
from ovos_utils.lang import standardize_lang_tag
from ovos_utils.log import LOG, deprecated, log_deprecation
from ovos_utils.metrics import Stopwatch
from padacioso.opm import PadaciosoPipeline as PadaciosoService
Expand Down Expand Up @@ -352,6 +353,7 @@ def get_pipeline(self, skips=None, session=None) -> Tuple[str, Callable]:

def _validate_session(self, message, lang):
# get session
lang = standardize_lang_tag(lang)
sess = SessionManager.get(message)
if sess.session_id == "default":
updated = False
Expand Down
60 changes: 32 additions & 28 deletions ovos_core/intent_services/converse_service.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import time
from threading import Event
from typing import Optional
from typing import Optional, List

from ovos_bus_client.message import Message
from ovos_bus_client.session import SessionManager, UtteranceState
from ovos_bus_client.session import SessionManager, UtteranceState, Session
from ovos_bus_client.util import get_message_lang
from ovos_workshop.permissions import ConverseMode, ConverseActivationMode

from ovos_config.config import Configuration
from ovos_config.locale import setup_locale
from ovos_plugin_manager.templates.pipeline import IntentMatch, PipelinePlugin
from ovos_utils import flatten_list
from ovos_utils.lang import standardize_lang_tag
from ovos_utils.log import LOG
from ovos_workshop.permissions import ConverseMode, ConverseActivationMode


class ConverseService(PipelinePlugin):
Expand All @@ -26,14 +28,7 @@ def __init__(self, bus):
self.bus.on('intent.service.active_skills.get', self.handle_get_active_skills)
self.bus.on("skill.converse.get_response.enable", self.handle_get_response_enable)
self.bus.on("skill.converse.get_response.disable", self.handle_get_response_disable)

@property
def config(self):
"""
Returns:
converse_config (dict): config for converse handling options
"""
return Configuration().get("skills", {}).get("converse") or {}
super().__init__(config=Configuration().get("skills", {}).get("converse") or {})

@property
def active_skills(self):
Expand All @@ -47,7 +42,8 @@ def active_skills(self, val):
for skill_id, ts in val:
session.activate_skill(skill_id)

def get_active_skills(self, message=None):
@staticmethod
def get_active_skills(message: Optional[Message] = None) -> List[str]:
"""Active skill ids ordered by converse priority
this represents the order in which converse will be called
Expand All @@ -57,12 +53,14 @@ def get_active_skills(self, message=None):
session = SessionManager.get(message)
return [skill[0] for skill in session.active_skills]

def deactivate_skill(self, skill_id, source_skill=None, message=None):
def deactivate_skill(self, skill_id: str, source_skill: Optional[str] = None,
message: Optional[Message] = None):
"""Remove a skill from being targetable by converse.
Args:
skill_id (str): skill to remove
source_skill (str): skill requesting the removal
message (Message): the bus message that requested deactivation
"""
source_skill = source_skill or skill_id
if self._deactivate_allowed(skill_id, source_skill):
Expand All @@ -81,7 +79,8 @@ def deactivate_skill(self, skill_id, source_skill=None, message=None):
if skill_id in self._consecutive_activations:
self._consecutive_activations[skill_id] = 0

def activate_skill(self, skill_id, source_skill=None, message=None):
def activate_skill(self, skill_id: str, source_skill: Optional[str] = None,
message: Optional[Message] = None) -> Optional[Session]:
"""Add a skill or update the position of an active skill.
The skill is added to the front of the list, if it's already in the
Expand All @@ -90,6 +89,7 @@ def activate_skill(self, skill_id, source_skill=None, message=None):
Args:
skill_id (str): identifier of skill to be added.
source_skill (str): skill requesting the removal
message (Message): the bus message that requested activation
"""
source_skill = source_skill or skill_id
if self._activate_allowed(skill_id, source_skill):
Expand All @@ -108,7 +108,7 @@ def activate_skill(self, skill_id, source_skill=None, message=None):
self._consecutive_activations[skill_id] += 1
return session

def _activate_allowed(self, skill_id, source_skill=None):
def _activate_allowed(self, skill_id: str, source_skill: Optional[str] = None) -> bool:
"""Checks if a skill_id is allowed to jump to the front of active skills list
- can a skill activate a different skill
Expand Down Expand Up @@ -166,7 +166,7 @@ def _activate_allowed(self, skill_id, source_skill=None):
return False # skill exceeded authorized consecutive number of activations
return True

def _deactivate_allowed(self, skill_id, source_skill=None):
def _deactivate_allowed(self, skill_id: str, source_skill: Optional[str] = None) -> bool:
"""Checks if a skill_id is allowed to be removed from active skills list
- can a skill deactivate a different skill
Expand All @@ -186,7 +186,7 @@ def _deactivate_allowed(self, skill_id, source_skill=None):
return False
return True

def _converse_allowed(self, skill_id):
def _converse_allowed(self, skill_id: str) -> bool:
"""Checks if a skill_id is allowed to converse
- is the skill blacklisted from conversing
Expand All @@ -208,7 +208,7 @@ def _converse_allowed(self, skill_id):
return False
return True

def _collect_converse_skills(self, message):
def _collect_converse_skills(self, message: Message) -> List[str]:
"""use the messagebus api to determine which skills want to converse
This includes all skills and external applications"""
session = SessionManager.get(message)
Expand Down Expand Up @@ -256,7 +256,7 @@ def handle_ack(msg):
self.bus.remove("skill.converse.pong", handle_ack)
return want_converse

def _check_converse_timeout(self, message):
def _check_converse_timeout(self, message: Message):
""" filter active skill list based on timestamps """
timeouts = self.config.get("skill_timeouts") or {}
def_timeout = self.config.get("timeout", 300)
Expand All @@ -265,7 +265,7 @@ def _check_converse_timeout(self, message):
skill for skill in session.active_skills
if time.time() - skill[1] <= timeouts.get(skill[0], def_timeout)]

def converse(self, utterances, skill_id, lang, message):
def converse(self, utterances: List[str], skill_id: str, lang: str, message: Message) -> bool:
"""Call skill and ask if they want to process the utterance.
Args:
Expand All @@ -278,6 +278,7 @@ def converse(self, utterances, skill_id, lang, message):
Returns:
handled (bool): True if handled otherwise False.
"""
lang = standardize_lang_tag(lang)
session = SessionManager.get(message)
session.lang = lang

Expand Down Expand Up @@ -312,7 +313,7 @@ def converse(self, utterances, skill_id, lang, message):
f'increasing "max_skill_runtime" in mycroft.conf might help alleviate this issue')
return False

def converse_with_skills(self, utterances, lang, message) -> Optional[IntentMatch]:
def converse_with_skills(self, utterances: List[str], lang: str, message: Message) -> Optional[IntentMatch]:
"""Give active skills a chance at the utterance
Args:
Expand All @@ -323,6 +324,7 @@ def converse_with_skills(self, utterances, lang, message) -> Optional[IntentMatc
Returns:
IntentMatch if handled otherwise None.
"""
lang = standardize_lang_tag(lang)
session = SessionManager.get(message)

# we call flatten in case someone is sending the old style list of tuples
Expand All @@ -344,21 +346,23 @@ def converse_with_skills(self, utterances, lang, message) -> Optional[IntentMatc
utterance=utterances[0])
return None

def handle_get_response_enable(self, message):
@staticmethod
def handle_get_response_enable(message: Message):
skill_id = message.data["skill_id"]
session = SessionManager.get(message)
session.enable_response_mode(skill_id)
if session.session_id == "default":
SessionManager.sync(message)

def handle_get_response_disable(self, message):
@staticmethod
def handle_get_response_disable(message: Message):
skill_id = message.data["skill_id"]
session = SessionManager.get(message)
session.disable_response_mode(skill_id)
if session.session_id == "default":
SessionManager.sync(message)

def handle_activate_skill_request(self, message):
def handle_activate_skill_request(self, message: Message):
# TODO imperfect solution - only a skill can activate itself
# someone can forge this message and emit it raw, but in OpenVoiceOS all
# skill messages should have skill_id in context, so let's make sure
Expand All @@ -370,7 +374,7 @@ def handle_activate_skill_request(self, message):
if sess.session_id == "default":
SessionManager.sync(message)

def handle_deactivate_skill_request(self, message):
def handle_deactivate_skill_request(self, message: Message):
# TODO imperfect solution - only a skill can deactivate itself
# someone can forge this message and emit it raw, but in ovos-core all
# skill message should have skill_id in context, so let's make sure
Expand All @@ -382,17 +386,17 @@ def handle_deactivate_skill_request(self, message):
if sess.session_id == "default":
SessionManager.sync(message)

def reset_converse(self, message):
def reset_converse(self, message: Message):
"""Let skills know there was a problem with speech recognition"""
lang = get_message_lang(message)
lang = get_message_lang()
try:
setup_locale(lang) # restore default lang
except Exception as e:
LOG.exception(f"Failed to set lingua_franca default lang to {lang}")

self.converse_with_skills([], lang, message)

def handle_get_active_skills(self, message):
def handle_get_active_skills(self, message: Message):
"""Send active skills to caller.
Argument:
Expand Down
28 changes: 17 additions & 11 deletions ovos_core/intent_services/fallback_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,17 @@
import operator
import time
from collections import namedtuple
from typing import Optional
from typing import Optional, List

from ovos_bus_client.message import Message
from ovos_bus_client.session import SessionManager
from ovos_workshop.permissions import FallbackMode

from ovos_config import Configuration
from ovos_plugin_manager.templates.pipeline import IntentMatch, PipelinePlugin
from ovos_utils import flatten_list
from ovos_utils.lang import standardize_lang_tag
from ovos_utils.log import LOG
from ovos_workshop.permissions import FallbackMode

FallbackRange = namedtuple('FallbackRange', ['start', 'stop'])

Expand All @@ -39,7 +42,7 @@ def __init__(self, bus):
self.bus.on("ovos.skills.fallback.deregister", self.handle_deregister_fallback)
super().__init__(self.fallback_config)

def handle_register_fallback(self, message):
def handle_register_fallback(self, message: Message):
skill_id = message.data.get("skill_id")
priority = message.data.get("priority") or 101

Expand All @@ -52,12 +55,12 @@ def handle_register_fallback(self, message):
else:
self.registered_fallbacks[skill_id] = priority

def handle_deregister_fallback(self, message):
def handle_deregister_fallback(self, message: Message):
skill_id = message.data.get("skill_id")
if skill_id in self.registered_fallbacks:
self.registered_fallbacks.pop(skill_id)

def _fallback_allowed(self, skill_id):
def _fallback_allowed(self, skill_id: str) -> bool:
"""Checks if a skill_id is allowed to fallback
- is the skill blacklisted from fallback
Expand All @@ -78,7 +81,8 @@ def _fallback_allowed(self, skill_id):
return False
return True

def _collect_fallback_skills(self, message, fb_range=FallbackRange(0, 100)):
def _collect_fallback_skills(self, message: Message,
fb_range: FallbackRange = FallbackRange(0, 100)) -> List[str]:
"""use the messagebus api to determine which skills have registered fallback handlers
This includes all skills and external applications"""
skill_ids = [] # skill_ids that already answered to ping
Expand Down Expand Up @@ -116,7 +120,7 @@ def handle_ack(msg):
self.bus.remove("ovos.skills.fallback.pong", handle_ack)
return fallback_skills

def attempt_fallback(self, utterances, skill_id, lang, message):
def attempt_fallback(self, utterances: List[str], skill_id: str, lang: str, message: Message) -> bool:
"""Call skill and ask if they want to process the utterance.
Args:
Expand Down Expand Up @@ -158,7 +162,8 @@ def attempt_fallback(self, utterances, skill_id, lang, message):
f'increasing "max_skill_runtime" in mycroft.conf might help alleviate this issue')
return False

def _fallback_range(self, utterances, lang, message, fb_range) -> Optional[IntentMatch]:
def _fallback_range(self, utterances: List[str], lang: str,
message: Message, fb_range: FallbackRange) -> Optional[IntentMatch]:
"""Send fallback request for a specified priority range.
Args:
Expand All @@ -171,6 +176,7 @@ def _fallback_range(self, utterances, lang, message, fb_range) -> Optional[Inten
Returns:
IntentMatch or None
"""
lang = standardize_lang_tag(lang)
# we call flatten in case someone is sending the old style list of tuples
utterances = flatten_list(utterances)
message.data["utterances"] = utterances # all transcripts
Expand All @@ -195,17 +201,17 @@ def _fallback_range(self, utterances, lang, message, fb_range) -> Optional[Inten
utterance=utterances[0])
return None

def high_prio(self, utterances, lang, message) -> Optional[IntentMatch]:
def high_prio(self, utterances: List[str], lang: str, message: Message) -> Optional[IntentMatch]:
"""Pre-padatious fallbacks."""
return self._fallback_range(utterances, lang, message,
FallbackRange(0, 5))

def medium_prio(self, utterances, lang, message) -> Optional[IntentMatch]:
def medium_prio(self, utterances: List[str], lang: str, message: Message) -> Optional[IntentMatch]:
"""General fallbacks."""
return self._fallback_range(utterances, lang, message,
FallbackRange(5, 90))

def low_prio(self, utterances, lang, message) -> Optional[IntentMatch]:
def low_prio(self, utterances: List[str], lang: str, message: Message) -> Optional[IntentMatch]:
"""Low prio fallbacks with general matching such as chat-bot."""
return self._fallback_range(utterances, lang, message,
FallbackRange(90, 101))
Expand Down
Loading

0 comments on commit 9680cb4

Please sign in to comment.