Skip to content

Commit

Permalink
fix:better_stop
Browse files Browse the repository at this point in the history
  • Loading branch information
JarbasAl committed Jan 9, 2025
1 parent 83ba17d commit 99858d0
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 16 deletions.
7 changes: 5 additions & 2 deletions ovos_core/intent_services/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ def _emit_match_message(self, match: Union[IntentHandlerMatch, PipelineMatch], m
message (Message): The messagebus data.
"""
reply = None
sess = SessionManager.get(message)
sess = match.updated_session or SessionManager.get(message)

# utterance fully handled by pipeline matcher
if isinstance(match, PipelineMatch):
Expand All @@ -303,10 +303,13 @@ def _emit_match_message(self, match: Union[IntentHandlerMatch, PipelineMatch], m
was_deactivated = match.skill_id in self._deactivations[sess.session_id]
if not was_deactivated:
sess.activate_skill(match.skill_id)
reply.context["session"] = sess.serialize()
# emit event for skills callback -> self.handle_activate
self.bus.emit(reply.forward(f"{match.skill_id}.activate"))

# update Session if modified by pipeline
reply.context["session"] = sess.serialize()

# finally emit reply message
self.bus.emit(reply)

def send_cancel_event(self, message):
Expand Down
1 change: 1 addition & 0 deletions ovos_core/intent_services/converse_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@ def converse_with_skills(self, utterances: List[str], lang: str, message: Messag
# handled == True -> emit "ovos.utterance.handled"
match_data={},
skill_id=skill_id,
updated_session=session,
utterance=utterances[0])
return None

Expand Down
48 changes: 34 additions & 14 deletions ovos_core/intent_services/stop_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,19 +52,21 @@ def get_active_skills(message: Optional[Message] = None) -> List[str]:
def _collect_stop_skills(self, message: Message) -> List[str]:
"""use the messagebus api to determine which skills can stop
This includes all skills and external applications"""
sess = SessionManager.get(message)

want_stop = []
skill_ids = []

active_skills = self.get_active_skills(message)
active_skills = [s for s in self.get_active_skills(message)
if s not in sess.blacklisted_skills]

if not active_skills:
return want_stop

event = Event()

def handle_ack(msg):
nonlocal event
nonlocal event, skill_ids
skill_id = msg.data["skill_id"]

# validate the stop pong
Expand Down Expand Up @@ -111,7 +113,24 @@ def stop_skill(self, skill_id: str, message: Message) -> bool:
LOG.error(f"{skill_id}: {error_msg}")
return False
elif result is not None:
return result.data.get('result', False)
stopped = result.data.get('result', False)
else:
stopped = False

if stopped:
sess = SessionManager.get(message)
state = sess.utterance_states.get(skill_id, "intent")
LOG.debug(f"skill response status: {state}")
if state == "response": # TODO this is never happening and it should...
LOG.debug(f"stopping {skill_id} in middle of get_response!")

# force-kill any ongoing get_response/converse/TTS - see @killable_event decorator
self.bus.emit(message.forward("mycroft.skills.abort_question", {"skill_id": skill_id}))
self.bus.emit(message.forward("ovos.skills.converse.force_timeout", {"skill_id": skill_id}))
# TODO - track if speech is coming from this skill! not currently tracked
self.bus.emit(message.reply("mycroft.audio.speech.stop",{"skill_id": skill_id}))

return stopped

def match_stop_high(self, utterances: List[str], lang: str, message: Message) -> Optional[PipelineMatch]:
"""If utterance is an exact match for "stop" , run before intent stage
Expand Down Expand Up @@ -140,6 +159,7 @@ def match_stop_high(self, utterances: List[str], lang: str, message: Message) ->
conf = 1.0

if is_global_stop:
LOG.info(f"Emitting global stop, {len(self.get_active_skills(message))} active skills")
# emit a global stop, full stop anything OVOS is doing
self.bus.emit(message.reply("mycroft.stop", {}))
return PipelineMatch(handled=True,
Expand All @@ -150,15 +170,15 @@ def match_stop_high(self, utterances: List[str], lang: str, message: Message) ->
if is_stop:
# check if any skill can stop
for skill_id in self._collect_stop_skills(message):
if skill_id in sess.blacklisted_skills:
LOG.debug(f"ignoring match, skill_id '{skill_id}' blacklisted by Session '{sess.session_id}'")
continue

LOG.debug(f"Checking if skill wants to stop: {skill_id}")
if self.stop_skill(skill_id, message):
LOG.info(f"Skill stopped: {skill_id}")
sess.disable_response_mode(skill_id)
return PipelineMatch(handled=True,
match_data={"conf": conf},
skill_id=skill_id,
utterance=utterance)
utterance=utterance,
updated_session=sess)
return None

def match_stop_medium(self, utterances: List[str], lang: str, message: Message) -> Optional[PipelineMatch]:
Expand Down Expand Up @@ -229,17 +249,17 @@ def match_stop_low(self, utterances: List[str], lang: str, message: Message) ->

# check if any skill can stop
for skill_id in self._collect_stop_skills(message):
if skill_id in sess.blacklisted_skills:
LOG.debug(f"ignoring match, skill_id '{skill_id}' blacklisted by Session '{sess.session_id}'")
continue

LOG.debug(f"Checking if skill wants to stop: {skill_id}")
if self.stop_skill(skill_id, message):
sess.disable_response_mode(skill_id)
return PipelineMatch(handled=True,
# emit instead of intent message
match_data={"conf": conf},
skill_id=skill_id, utterance=utterance)
skill_id=skill_id,
utterance=utterance,
updated_session=sess)

# emit a global stop, full stop anything OVOS is doing
LOG.debug(f"Emitting global stop signal, {len(self.get_active_skills(message))} active skills")
self.bus.emit(message.reply("mycroft.stop", {}))
return PipelineMatch(handled=True,
# emit instead of intent message {"conf": conf},
Expand Down

0 comments on commit 99858d0

Please sign in to comment.