Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ license = "apache-2.0"
authors = [{name = "jarbasAi", email = "jarbasai@mailfence.com"}]
requires-python = ">=3.9"
dependencies = [
"ovos-utils>= 0.7.0,<1.0.0",
"ovos_bus_client>=2.6.0a1,<3.0.0", # HandlerLifecycle done-signal util (#246)
"ovos-utils>= 0.13.3a2,<1.0.0", # FakeBus folds before handlers (ovos-utils#396) — keeps in-place add_context mutations alive so intent-layer gating works
"ovos_bus_client>=2.6.2a2,<3.0.0", # HandlerLifecycle done-signal util (#246) + singleton-registry SessionManager (2.6.2a2)
"ovos-config>=0.0.12,<3.0.0",
"ovos-spec-tools>=0.16.1a2", # carries the adapt-free intent-definition primitives (OVOS-INTENT-4)
"ovos-spec-tools>=1.2.3a1", # canonical SessionManager registry + OVOS-INTENT-4 intent-definition primitives
"ovos-yes-no-plugin>=0.3.0,<1.0.0",
"ovos-option-matcher-fuzzy-plugin>=0.0.1,<1.0.0",
"ovos-number-parser>=0.0.1,<1.0.0",
Expand All @@ -26,9 +26,9 @@ dependencies = [

[project.optional-dependencies]
test = [
"ovos-core>=0.0.8a50",
"ovos-core>=2.4.0a1", # orchestrator owns ovos.utterance.handled on the matched path (PIPELINE-1 §9.5)
"ovoscope>=0.1.0",
"ovos-adapt-parser>=1.3.1a1",
"ovos-adapt-parser>=1.4.2a1",
"pytest",
"pytest-cov",
"ovos-translate-server-plugin",
Expand Down
37 changes: 31 additions & 6 deletions test/unittests/skills/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -355,16 +355,41 @@ def test_on_event_end(self):
self.assertEqual(context["skill_id"], self.skill_id)
self.assertEqual(context["session"]["session_id"], "sess1")

def test_on_event_end_is_intent_still_emits_utterance_handled(self):
# the ovos.utterance.handled emission must be PRESERVED alongside the
# delegated .complete done-signal when is_intent=True
def test_on_event_end_intent_defers_utterance_handled_to_core(self):
# PIPELINE-1 §9.5: with a modern ovos-core (>=2.3.0a1) the orchestrator
# owns the universal `ovos.utterance.handled` end-marker on every
# terminal path — the matched path included. Workshop must NOT also
# emit it (consumers would see the marker twice); only the delegated
# `mycroft.skill.handler.complete` done-signal is emitted here.
from unittest.mock import patch
from ovos_bus_client.message import Message
from ovos_spec_tools import SpecMessage
msg = Message("trigger", {}, {})
skill_data = {"name": "TestSkill.handle_test"}
captured = self._capture(OVOSSkill._on_event_end, msg,
"mycroft.skill.handler", dict(skill_data),
True)
with patch("ovos_workshop.skills.ovos._core_owns_utterance_handled",
return_value=True):
captured = self._capture(OVOSSkill._on_event_end, msg,
"mycroft.skill.handler",
dict(skill_data), True)
types = [c[0] for c in captured]
self.assertIn("mycroft.skill.handler.complete", types)
self.assertNotIn(SpecMessage.UTTERANCE_HANDLED.value, types)

def test_on_event_end_intent_emits_utterance_handled_legacy(self):
# Migration-window back-compat: with an absent/old ovos-core that does
# not yet emit `ovos.utterance.handled` on the matched path, workshop
# must still emit it alongside the delegated `.complete` done-signal so
# spec consumers always observe exactly one end-marker.
from unittest.mock import patch
from ovos_bus_client.message import Message
from ovos_spec_tools import SpecMessage
msg = Message("trigger", {}, {})
skill_data = {"name": "TestSkill.handle_test"}
with patch("ovos_workshop.skills.ovos._core_owns_utterance_handled",
return_value=False):
captured = self._capture(OVOSSkill._on_event_end, msg,
"mycroft.skill.handler",
dict(skill_data), True)
types = [c[0] for c in captured]
self.assertIn("mycroft.skill.handler.complete", types)
self.assertIn(SpecMessage.UTTERANCE_HANDLED.value, types)
Expand Down
Loading