Stop Pipeline¶
Maturity — Mature ⬤⬤⬤⬤⬤
Long-lived and actively maintained. Depend on it freely. Rated by repository health, not version.
In a nutshell
This is the part of OVOS that listens for "stop", "cancel", or the same word in your language and makes the assistant quit whatever it is doing: interrupting a spoken reply, ending a question, or halting a task a skill started. Because being able to stop is so essential to a voice assistant, OVOS treats it as a built-in, always-on feature rather than an optional add-on. It works in any language that ships the right word list. For the wider system this fits into, see the Fallback Pipeline or the Glossary.
This is a flow stage: part of every standard pipeline rather than a matcher you choose between.
The rest of this page is for people deploying or customizing OVOS. If you only wanted to know what this stage does, you are done.
📐 Formal specification
The stop plugin is specified by OVOS-STOP-1: Stop Pipeline Plugin, built on OVOS-PIPELINE-1. See the spec index.
The stop pipeline is a core component of the OpenVoiceOS (OVOS) pipeline architecture. It defines the logic responsible for stopping ongoing interactions with active skills. This includes aborting responses, halting speech, and terminating background tasks that skills may be performing.
Because stopping is a fundamental feature of a voice assistant, it is implemented as a dedicated pipeline plugin, rather than a fallback or intent handler. STOP-1 is emphatic that stop is a pipeline plugin and not a skill. skill-ovos-stop is superseded. PIPELINE-1's first-match-wins rule places a high-confidence stop stage first in session.pipeline (STOP-1 §7). That placement is why stop works: the stage intercepts "stop" before any other pipeline plugin claims the bare word.
Spec model and topic names
STOP-1 distinguishes two outcomes, both via reserved intent_names. A generic stop cascades to the handler with the strongest claim on the session: the plugin builds its candidate list from session.response_mode and session.active_handlers (the recency record, PIPELINE-1 §7.1), pings them with ovos.stop.ping, collects ovos.stop.pong (can_handle) within a recommended 0.5s ceiling, and returns a Match on the reserved stop name targeting the first positive responder in candidate order, dispatched on <skill_id>:stop. A handler that does not answer within the timeout counts as can_handle: false.
global_stop covers the three cases where there is nothing to target (STOP-1 §5.1): explicit "stop everything" vocabulary, a generic stop with active_handlers empty (or containing only the stop plugin itself), and a ping round that produced no positive responder (§4.1 step 5). Its Match clears active_handlers, converse_handlers and response_mode atomically, and its handler broadcasts ovos.stop, which every active component subscribes to.
| Spec topic (STOP-1 §8) | Legacy name |
|---|---|
ovos.stop.ping / ovos.stop.pong |
{skill_id}.stop.ping / skill.stop.pong |
<skill_id>:stop — targeted-stop dispatch (reserved name) |
stop:skill → {skill_id}.stop |
<pipeline_id>:global_stop — global-stop dispatch |
stop:global |
ovos.stop — global-stop broadcast |
mycroft.stop |
session.active_handlers — recency input to the cascade |
Session.active_skills |
Implementation¶
Module: ovos_core.intent_services.stop_service.StopService
Pipeline plugin ID: ovos-stop-pipeline-plugin
Stage names: ovos-stop-pipeline-plugin-high, ovos-stop-pipeline-plugin-medium, ovos-stop-pipeline-plugin-low (deprecated aliases: stop_high, stop_medium, stop_low)
StopService subclasses ConfidenceMatcherPipeline (it stamps its pipeline_id, ovos-stop-pipeline-plugin, as the skill_id on the matches it produces). Because it is a ConfidenceMatcherPipeline, the single base plugin ID auto-expands into three confidence-tier matchers: match_high, match_medium and match_low. You reference these in the pipeline as ovos-stop-pipeline-plugin-high, -medium, and -low. It ships inside ovos-core:
[project.entry-points."opm.pipeline"]
ovos-stop-pipeline-plugin = "ovos_core.intent_services.stop_service:StopService"
Purpose¶
A voice assistant must always be capable of responding to a "stop" command. Whether the user says "stop," "cancel," or another localized phrase, OVOS must quickly:
-
Determine if a skill is actively responding
-
Allow skills to confirm whether they can be stopped
-
Abort conversations, questions, or spoken responses
The stop pipeline guarantees this behavior through a flexible plugin system and localized vocab matching.
Saying \"stop\" still needs the wake word — there is no barge-in
Nothing interrupts the assistant just because you start talking. A stop command is an
ordinary utterance: wake word first, then "stop". listener.mute_during_output
(default false) only controls whether the microphone keeps listening for the wake word
while audio plays, and listener.fake_barge_in only lowers playback volume while a
recording is in progress. Neither cancels speech on its own.
How it works¶
The stop pipeline exposes three confidence tiers.
High-confidence (stop_high)¶
Triggered when a user says an exact match (voc_match(..., exact=True)) for the stop or global_stop vocab, e.g.:
-
"Stop"
-
"Cancel"
-
"Parar" (in Portuguese)
-
"Stopp" (in German)
The plugin:
-
Collects the session's stop candidates, skipping session-blacklisted ones and the stop plugin itself. A skill holding the session's
response_modewindow comes first, ahead of the recency list; the session's active handlers follow in recency order. -
Emits the
ovos.stop.pingbroadcast STOP-1 defines, and also pings each active handler on its per-skill topic{skill_id}.stop.ping. Both go out on every stop. The per-skill form is what reaches skills today, because theovos-workshopbase class subscribes to that one and not to the broadcast; keep the per-skill subscription until the base class moves.ovos-corelogs a warning that the per-skill emission is a compatibility measure and names the release that drops it. The plugin then waits up to0.5sforovos.stop.pong(legacy:skill.stop.pong) replies carryingcan_handle. -
Dispatches
<skill_id>:stop(legacy:{skill_id}.stop) to the first positive responder in candidate order. Pongs are re-sorted into that order before the winner is picked, so the answer that arrived first does not decide the round. -
If no skill is active, no responder answered positively, or the utterance matched
global_stop, emits a global stop:ovos.stop(legacy:mycroft.stop).
Medium-confidence (stop_medium)¶
A fuzzy (exact=False) match of the same stop / global_stop vocab, for phrases that contain a stop command but are not exact. When it matches, it delegates to match_low to compute a confidence score.
Low-confidence (stop_low)¶
Scores the utterance against the stop vocab list via fuzzy matching (match_one), adds a small bonus when active skills are present, and rejects anything below min_conf (default 0.5). Used as a permissive catch-all so phrases like "can you please stop?" still reach the stop logic.
flowchart TD
U[Utterance] --> V{Matches stop /\nglobal_stop vocab?}
V -->|no| N[No match]
V -->|global_stop or\nno active skills| G[Global stop\nbroadcast ovos.stop]
V -->|yes, skills active| P[Ping active skills\n{skill_id}.stop.ping]
P --> W{Any skill replies\ncan_handle?}
W -->|yes| D[Dispatch stop to\nfirst candidate responder]
W -->|no, timeout| G
Diagram: an utterance that matches the stop vocabulary either targets the highest-ranked candidate skill that confirms it can stop, or falls back to a global stop broadcast when there is nothing to target or no skill responds in time.
Localization¶
The plugin supports stop commands in multiple languages using .voc files bundled in ovos-core under ovos_core/intent_services/locale/<lang>/:
match_high/match_medium look up the stop and global_stop vocab groups. match_low uses the stop list only. Not every language ships both files (some provide only stop.voc).
Session Integration¶
The stop plugin interfaces with the OVOS session system:
-
Skills that respond to
stopwill be removed from active skill list -
Session blacklists are respected, blacklisted skills will not be pinged
-
Session state is updated after each successful stop
Bus Events¶
| Event | Direction | Purpose |
|---|---|---|
<pipeline_id>:global_stop (legacy: stop:global) |
in | Global-stop dispatch — its handler emits the ovos.stop broadcast (and ovos.utterance.handled) |
<skill_id>:stop (legacy: stop:skill → {skill_id}.stop) |
out | Targeted stop dispatch to one skill |
ovos.stop.ping |
out | Broadcast asking active handlers whether they can stop, per STOP-1. The ovos-workshop base class does not subscribe to it yet |
{skill_id}.stop.ping |
out | The same question addressed to one skill, emitted alongside the broadcast. The form skills actually answer, since the base class subscribes to it rather than the broadcast. Removed in a future ovos-core |
ovos.stop.pong (legacy: skill.stop.pong) |
in | Handler's can_handle reply |
ovos.stop (legacy: mycroft.stop) |
out | Universal stop broadcast |
<skill_id>:stop and <pipeline_id>:global_stop are dispatch topics and fire the handler-lifecycle trio. The ovos.stop.* topics and ovos.stop do not.
Configuration¶
The service reads its config from mycroft.conf under skills.stop. The only key it consults is min_conf (default 0.5), the floor used by the low-confidence matcher:
Design Philosophy¶
-
Low latency: skills are pinged with a 0.5s wait, so stop resolves quickly
-
Extensible: other plugins can extend or override this pipeline
-
Localized: matching is language-aware via per-language vocab
-
Resilient: falls back to a global
ovos.stopbroadcast if no handler responds positively
Summary¶
The stop pipeline ensures that OVOS is always in control. It handles interrupting a skill, canceling a conversation, or shutting down all interactions, with a language-aware foundation built into StopService.
It is not considered optional. All OVOS installations should include this pipeline by default.
Read next: Fallback Pipeline Related: Persona Pipeline · Converse Pipeline · OCP Pipeline