diff --git a/ovos_core/intent_services/converse_service.py b/ovos_core/intent_services/converse_service.py index c62b142df8bb..81313ab7efd0 100644 --- a/ovos_core/intent_services/converse_service.py +++ b/ovos_core/intent_services/converse_service.py @@ -330,6 +330,9 @@ def handle_activate_skill_request(self, message): skill_id = message.data['skill_id'] source_skill = message.context.get("skill_id") self.activate_skill(skill_id, source_skill, message) + sess = SessionManager.get(message) + if sess.session_id == "default": + SessionManager.sync(message) def handle_deactivate_skill_request(self, message): # TODO imperfect solution - only a skill can deactivate itself @@ -339,6 +342,9 @@ def handle_deactivate_skill_request(self, message): skill_id = message.data['skill_id'] source_skill = message.context.get("skill_id") or skill_id self.deactivate_skill(skill_id, source_skill, message) + sess = SessionManager.get(message) + if sess.session_id == "default": + SessionManager.sync(message) def reset_converse(self, message): """Let skills know there was a problem with speech recognition""" diff --git a/test/end2end/session/test_converse.py b/test/end2end/session/test_converse.py index c114f98534cc..984a7273c69c 100644 --- a/test/end2end/session/test_converse.py +++ b/test/end2end/session/test_converse.py @@ -431,4 +431,97 @@ def converse_capture(): self.assertEqual(messages[8].data["session_data"]["active_skills"][0][0], self.skill_id) self.assertEqual(messages[8].data["session_data"]["active_skills"][1][0], self.other_skill_id) + messages = [] + converse_capture() + + def external_deactivate(): + nonlocal messages + + utt = Message("test_deactivate") + self.core.bus.emit(utt) + + self.assertEqual(SessionManager.default_session.active_skills[0][0], self.other_skill_id) + # confirm all expected messages are sent + expected_messages = [ + "test_deactivate", + "intent.service.skills.deactivate", + "intent.service.skills.deactivated", + "ovos-tskill-abort.openvoiceos.deactivate", + "ovos.session.update_default" + ] + wait_for_n_messages(len(expected_messages)) + + self.assertEqual(len(expected_messages), len(messages)) + + mtypes = [m.msg_type for m in messages] + for m in expected_messages: + self.assertTrue(m in mtypes) + + # verify skill is no longer in active skills + self.assertEqual(SessionManager.default_session.active_skills[0][0], self.other_skill_id) + self.assertEqual(len(SessionManager.default_session.active_skills), 1) + + # verify default session is now updated + self.assertEqual(messages[-1].msg_type, "ovos.session.update_default") + self.assertEqual(messages[-1].data["session_data"]["session_id"], "default") + # test deserialization of payload + sess = Session.deserialize(messages[-1].data["session_data"]) + self.assertEqual(sess.session_id, "default") + # test that active skills list has been updated + self.assertEqual(len(sess.active_skills), 1) + self.assertEqual(sess.active_skills[0][0], self.other_skill_id) + self.assertEqual(len(messages[-1].data["session_data"]["active_skills"]), 1) + self.assertEqual(messages[-1].data["session_data"]["active_skills"][0][0], self.other_skill_id) + + messages = [] + + external_deactivate() + + def external_activate(): + nonlocal messages + + self.assertEqual(SessionManager.default_session.active_skills[0][0], self.other_skill_id) + utt = Message("test_activate") + self.core.bus.emit(utt) + self.assertEqual(SessionManager.default_session.active_skills[0][0], self.skill_id) + # confirm all expected messages are sent + expected_messages = [ + "test_activate", + "intent.service.skills.activate", + "intent.service.skills.activated", + f"{self.skill_id}.activate", + "ovos.session.update_default", + "active_skill_request", # backwards compat namespace classic core + "intent.service.skills.activated", + f"{self.skill_id}.activate", + "ovos.session.update_default" + ] + wait_for_n_messages(len(expected_messages)) + + self.assertEqual(len(expected_messages), len(messages)) + + mtypes = [m.msg_type for m in messages] + for m in expected_messages: + self.assertTrue(m in mtypes) + + # verify skill is again in active skills + self.assertEqual(SessionManager.default_session.active_skills[0][0], self.skill_id) + self.assertEqual(len(SessionManager.default_session.active_skills), 2) + + # verify default session is now updated + self.assertEqual(messages[-1].msg_type, "ovos.session.update_default") + self.assertEqual(messages[-1].data["session_data"]["session_id"], "default") + # test deserialization of payload + sess = Session.deserialize(messages[-1].data["session_data"]) + self.assertEqual(sess.session_id, "default") + # test that active skills list has been updated + self.assertEqual(len(sess.active_skills), 2) + self.assertEqual(sess.active_skills[0][0], self.skill_id) + self.assertEqual(len(messages[-1].data["session_data"]["active_skills"]), 2) + self.assertEqual(messages[-1].data["session_data"]["active_skills"][0][0], self.skill_id) + + messages = [] + + external_activate() +