Migrating Through the ovos-workshop 7.0.0 Release Train¶
In a nutshell
Skill maintainers are affected. Four ovos-workshop major versions
landed in about a day (4.0.0 → 7.0.0), each breaking a different part
of the OVOSSkill family, and the later-removed CommonQuerySkill
belongs to the same train. Fix it by applying all four OVOSSkill
changes at once and dropping CommonQuerySkill in favor of the
pipeline-plugin approach.
The ovos-workshop 2025-06 release train (4.0.0 → 7.0.0)¶
ovos-workshop went through four major-version breaks on the OVOSSkill
family in the space of about a day, each one landing on top of the last
before the previous change had even settled. A skill author jumping the
gap felt it as a moving target: can_answer went abstract, converse moved
out to its own base class, can_stop briefly went hard-abstract then was
loosened hours later, and that new base class's own method name turned out to
be wrong for about a day before being renamed. Anyone upgrading past a pre-2025-06
workshop version in one hop needs to treat all four changes as landing at
once, not as separable steps.
Four major versions of ovos-workshop shipped on the same day
(2025-06-07/08). Each is a separate breaking change to the OVOSSkill
family. If you are jumping from a pre-2025-06 workshop version to anything
after 7.0.0, expect all four of these to apply at once.
v4.0.0: FallbackSkill.can_answer becomes mandatory. (At 4.0.0 the base
implementation raised NotImplementedError at runtime; true abc.ABCMeta enforcement —
the skill refusing to load without an implementation — arrived later, in 9.3.9a1. See
Fallback Skills.)
# old: default True if any handler registered, no override needed
class MySkill(FallbackSkill):
def handle_fallback(self, message):
...
# new: must implement can_answer explicitly
class MySkill(FallbackSkill):
def can_answer(self, utterances: list[str], lang: str) -> bool:
return True # or real logic
def handle_fallback(self, message):
...
FallbackSkill.make_intent_failure_handler(cls, bus) (the old mycroft-style
bus-driven fallback dispatcher) is removed with it (ovos-workshop c066bc3, #336).
v5.0.0: converse moves out of OVOSSkill into its own base class.
# old: converse lived directly on OVOSSkill
class MySkill(OVOSSkill):
def converse(self, message=None):
...
# new: subclass ConversationalSkill (it already extends OVOSSkill)
from ovos_workshop.skills.converse import ConversationalSkill
class MySkill(ConversationalSkill):
def can_converse(self, message) -> bool:
return True
def converse(self, message=None):
...
An OVOSSkill subclass that overrides converse() without also inheriting
ConversationalSkill compiles fine but is silently never called by the
pipeline (ovos-workshop f725f5e, #339).
v6.0.0 / v6.0.1: can_stop conditional abstract method.
can_stop(self, message) briefly became a hard @abc.abstractmethod
(10f9781, #344) then was loosened the same day to only require
overriding if the skill also overrides stop/stop_session
(813f7b5, #346, released as 6.0.1). If you implement stop() or
stop_session(), also implement can_stop().
v7.0.0: can_answer on ConversationalSkill renamed to can_converse.
The v5.0.0 base class shipped with the wrong method name for about a day. Rename
can_answer → can_converse in any ConversationalSkill subclass
(ovos-workshop 1fdd532, #348).
Lifecycle:
| Change | Active | Deprecated but functional | Dropped |
|---|---|---|---|
FallbackSkill.can_answer concrete/optional |
before 4.0.0 (2025-06-07) |
unverified | 4.0.0 |
converse() on OVOSSkill directly |
before 5.0.0 (2025-06-07) |
unverified | 5.0.0 |
stop_is_implemented property / concrete can_stop |
before 6.0.0 |
6.0.1 (conditional requirement) |
6.0.0 (briefly hard), loosened in 6.0.1 |
ConversationalSkill.can_answer |
5.0.0 to 6.0.1 (about one day) |
none | 7.0.0 |
CommonQuerySkill removal¶
CommonQuerySkill sat deprecation-flagged for the better part of two
years before it was finally cut in one commit. There is no successor
class, but ovos-workshop still ships the replacement: the
@common_query decorator on a plain OVOSSkill. The removal only
completed a migration that had already happened underneath it: the
matching hardcoded common-query wiring inside ovos-core itself had been
pulled out earlier, when the whole intent-service module turned into a
config-driven OPM pipeline factory, so by the time the skill class was
deleted, common-query matching already lived in whichever pipeline plugin
happened to own it.
CommonQuerySkill had been deprecation-flagged since ovos-workshop
4.0.0 and was deleted entirely (259 lines, including the CQSMatchLevel
enum and CQS_match_query_phrase/CQS_action abstract methods) in
6382d0a (#400, 2026-04-08), months after the 8.0.0 release, first shipping in
8.0.4a3. There is no successor class: a plain
OVOSSkill joins common-query by decorating a method with @common_query()
(the removed class's own deprecation warning said exactly this). The matching
and ranking are dispatched by the common-query pipeline plugin. On ovos-core itself, the equivalent
hardcoded common-query wiring was removed from ovos_core.intent_services
in 62024dbf98 (#690, 2025-06-10, first stable release 2.1.0) when the
whole intent-service module became a config-driven OPM pipeline factory.
Lifecycle:
| Change | Active | Deprecated but functional | Dropped |
|---|---|---|---|
ovos_workshop.skills.common_query_skill.CommonQuerySkill |
before 4.0.0 |
4.0.0 until removal |
6382d0a (2026-04-08, post-8.0.0, 8.0.4a3) |
ovos-core hardcoded common-query wiring |
before 62024dbf98 |
unverified | 62024dbf98 (2.1.0, 2025-06-10) |
Read next: Updating From Older OVOS Related: For Skill Maintainers · Version-Compatible Skills & Plugins