Skip to content

Commit 698ef0e

Browse files
📝 Add docstrings to stop
Docstrings generation was requested by @JarbasAl. * #643 (comment) The following files were modified: * `ovos_core/intent_services/__init__.py` * `ovos_core/intent_services/converse_service.py` * `ovos_core/intent_services/stop_service.py`
1 parent 4fa2355 commit 698ef0e

File tree

3 files changed

+176
-46
lines changed

3 files changed

+176
-46
lines changed

ovos_core/intent_services/__init__.py

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -268,12 +268,31 @@ def _handle_deactivate(self, message):
268268
self._deactivations[sess.session_id].append(skill_id)
269269

270270
def _emit_match_message(self, match: Union[IntentHandlerMatch, PipelineMatch], message: Message):
271-
"""Update the message data with the matched utterance information and
272-
activate the corresponding skill if available.
273-
271+
"""
272+
Emit a reply message for a matched intent, updating session and skill activation.
273+
274+
This method processes matched intents from either a pipeline matcher or an intent handler,
275+
creating a reply message with matched intent details and managing skill activation.
276+
274277
Args:
275-
match (IntentHandlerMatch): The matched utterance object.
276-
message (Message): The messagebus data.
278+
match (Union[IntentHandlerMatch, PipelineMatch]): The matched intent object containing
279+
utterance and matching information.
280+
message (Message): The original messagebus message that triggered the intent match.
281+
282+
Details:
283+
- Handles two types of matches: PipelineMatch and IntentHandlerMatch
284+
- Creates a reply message with matched intent data
285+
- Activates the corresponding skill if not previously deactivated
286+
- Updates session information
287+
- Emits the reply message on the messagebus
288+
289+
Side Effects:
290+
- Modifies session state
291+
- Emits a messagebus event
292+
- Can trigger skill activation events
293+
294+
Returns:
295+
None
277296
"""
278297
reply = None
279298
sess = match.updated_session or SessionManager.get(message)
@@ -313,6 +332,24 @@ def _emit_match_message(self, match: Union[IntentHandlerMatch, PipelineMatch], m
313332
self.bus.emit(reply)
314333

315334
def send_cancel_event(self, message):
335+
"""
336+
Emit events and play a sound when an utterance is canceled.
337+
338+
Logs the cancellation with the specific cancel word, plays a predefined cancel sound,
339+
and emits multiple events to signal the utterance cancellation.
340+
341+
Parameters:
342+
message (Message): The original message that triggered the cancellation.
343+
344+
Events Emitted:
345+
- 'mycroft.audio.play_sound': Plays a cancel sound from configuration
346+
- 'ovos.utterance.cancelled': Signals that the utterance was canceled
347+
- 'ovos.utterance.handled': Indicates the utterance processing is complete
348+
349+
Notes:
350+
- Uses the default cancel sound path 'snd/cancel.mp3' if not specified in configuration
351+
- Ensures events are sent as replies to the original message
352+
"""
316353
LOG.info("utterance canceled, cancel_word:" + message.context.get("cancel_word"))
317354
# play dedicated cancel sound
318355
sound = Configuration().get('sounds', {}).get('cancel', "snd/cancel.mp3")

ovos_core/intent_services/converse_service.py

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -313,15 +313,29 @@ def converse(self, utterances: List[str], skill_id: str, lang: str, message: Mes
313313
return False
314314

315315
def converse_with_skills(self, utterances: List[str], lang: str, message: Message) -> Optional[PipelineMatch]:
316-
"""Give active skills a chance at the utterance
317-
316+
"""
317+
Attempt to converse with active skills for a given set of utterances.
318+
319+
Iterates through active skills to find one that can handle the utterance. Filters skills based on timeout and blacklist status.
320+
318321
Args:
319-
utterances (list): list of utterances
320-
lang (string): 4 letter ISO language code
321-
message (Message): message to use to generate reply
322-
322+
utterances (List[str]): List of utterance strings to process
323+
lang (str): 4-letter ISO language code for the utterances
324+
message (Message): Message context for generating a reply
325+
323326
Returns:
324-
IntentMatch if handled otherwise None.
327+
PipelineMatch: Match details if a skill successfully handles the utterance, otherwise None
328+
- handled (bool): Whether the utterance was fully handled
329+
- match_data (dict): Additional match metadata
330+
- skill_id (str): ID of the skill that handled the utterance
331+
- updated_session (Session): Current session state after skill interaction
332+
- utterance (str): The original utterance processed
333+
334+
Notes:
335+
- Standardizes language tag
336+
- Filters out blacklisted skills
337+
- Checks for skill conversation timeouts
338+
- Attempts conversation with each eligible skill
325339
"""
326340
lang = standardize_lang_tag(lang)
327341
session = SessionManager.get(message)

ovos_core/intent_services/stop_service.py

Lines changed: 113 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,25 @@ def get_active_skills(message: Optional[Message] = None) -> List[str]:
5050
return [skill[0] for skill in session.active_skills]
5151

5252
def _collect_stop_skills(self, message: Message) -> List[str]:
53-
"""use the messagebus api to determine which skills can stop
54-
This includes all skills and external applications"""
53+
"""
54+
Collect skills that can be stopped based on a ping-pong mechanism.
55+
56+
This method determines which active skills can handle a stop request by sending
57+
a stop ping to each active skill and waiting for their acknowledgment.
58+
59+
Parameters:
60+
message (Message): The original message triggering the stop request.
61+
62+
Returns:
63+
List[str]: A list of skill IDs that can be stopped. If no skills explicitly
64+
indicate they can stop, returns all active skills.
65+
66+
Notes:
67+
- Excludes skills that are blacklisted in the current session
68+
- Uses a non-blocking event mechanism to collect skill responses
69+
- Waits up to 0.5 seconds for skills to respond
70+
- Falls back to all active skills if no explicit stop confirmation is received
71+
"""
5572
sess = SessionManager.get(message)
5673

5774
want_stop = []
@@ -66,6 +83,23 @@ def _collect_stop_skills(self, message: Message) -> List[str]:
6683
event = Event()
6784

6885
def handle_ack(msg):
86+
"""
87+
Handle acknowledgment from skills during the stop process.
88+
89+
This method is a nested function used in skill stopping negotiation. It validates and tracks skill responses to a stop request.
90+
91+
Parameters:
92+
msg (Message): Message containing skill acknowledgment details.
93+
94+
Side Effects:
95+
- Modifies the `want_stop` list with skills that can handle stopping
96+
- Updates the `skill_ids` list to track which skills have responded
97+
- Sets the threading event when all active skills have responded
98+
99+
Notes:
100+
- Checks if a skill can handle stopping based on multiple conditions
101+
- Ensures all active skills provide a response before proceeding
102+
"""
69103
nonlocal event, skill_ids
70104
skill_id = msg.data["skill_id"]
71105

@@ -96,15 +130,28 @@ def handle_ack(msg):
96130
return want_stop or active_skills
97131

98132
def stop_skill(self, skill_id: str, message: Message) -> bool:
99-
"""Tell a skill to stop anything it's doing,
100-
taking into account the message Session
101-
133+
"""
134+
Stop a skill's ongoing activities and manage its session state.
135+
136+
Sends a stop command to a specific skill and handles its response, ensuring
137+
that any active interactions or processes are terminated. The method checks
138+
for errors, verifies the skill's stopped status, and emits additional signals
139+
to forcibly abort ongoing actions like conversations, questions, or speech.
140+
102141
Args:
103-
skill_id: skill to query.
104-
message (Message): message containing interaction info.
105-
142+
skill_id (str): Unique identifier of the skill to be stopped.
143+
message (Message): The original message context containing interaction details.
144+
106145
Returns:
107-
handled (bool): True if handled otherwise False.
146+
bool: True if the skill was successfully stopped, False otherwise.
147+
148+
Raises:
149+
Logs error if skill stop request encounters an issue.
150+
151+
Notes:
152+
- Emits multiple bus messages to ensure complete skill termination
153+
- Checks and handles different skill interaction states
154+
- Supports force-stopping of conversations, questions, and speech
108155
"""
109156
stop_msg = message.reply(f"{skill_id}.stop")
110157
result = self.bus.wait_for_response(stop_msg, f"{skill_id}.stop.response")
@@ -133,15 +180,28 @@ def stop_skill(self, skill_id: str, message: Message) -> bool:
133180
return stopped
134181

135182
def match_stop_high(self, utterances: List[str], lang: str, message: Message) -> Optional[PipelineMatch]:
136-
"""If utterance is an exact match for "stop" , run before intent stage
137-
138-
Args:
139-
utterances (list): list of utterances
140-
lang (string): 4 letter ISO language code
141-
message (Message): message to use to generate reply
142-
183+
"""
184+
Handles high-confidence stop requests by matching exact stop vocabulary and managing skill stopping.
185+
186+
Attempts to stop skills when an exact "stop" or "global_stop" command is detected. Performs the following actions:
187+
- Identifies the closest language match for vocabulary
188+
- Checks for global stop command when no active skills exist
189+
- Emits a global stop message if applicable
190+
- Attempts to stop individual skills if a stop command is detected
191+
- Disables response mode for stopped skills
192+
193+
Parameters:
194+
utterances (List[str]): List of user utterances to match against stop vocabulary
195+
lang (str): Four-letter ISO language code for language-specific matching
196+
message (Message): Message context for generating appropriate responses
197+
143198
Returns:
144-
PipelineMatch if handled otherwise None.
199+
Optional[PipelineMatch]: Match result indicating whether stop was handled, with optional skill and session information
200+
- Returns None if no stop action could be performed
201+
- Returns PipelineMatch with handled=True for successful global or skill-specific stop
202+
203+
Raises:
204+
No explicit exceptions raised, but may log debug/info messages during processing
145205
"""
146206
lang = self._get_closest_lang(lang)
147207
if lang is None: # no vocs registered for this lang
@@ -182,16 +242,26 @@ def match_stop_high(self, utterances: List[str], lang: str, message: Message) ->
182242
return None
183243

184244
def match_stop_medium(self, utterances: List[str], lang: str, message: Message) -> Optional[PipelineMatch]:
185-
""" if "stop" intent is in the utterance,
186-
but it contains additional words not in .intent files
187-
188-
Args:
189-
utterances (list): list of utterances
190-
lang (string): 4 letter ISO language code
191-
message (Message): message to use to generate reply
192-
245+
"""
246+
Handle stop intent with additional context beyond simple stop commands.
247+
248+
This method processes utterances that contain "stop" or global stop vocabulary but may include
249+
additional words not explicitly defined in intent files. It performs a medium-confidence
250+
intent matching for stop requests.
251+
252+
Parameters:
253+
utterances (List[str]): List of input utterances to analyze
254+
lang (str): Four-letter ISO language code for localization
255+
message (Message): Message context for generating appropriate responses
256+
193257
Returns:
194-
PipelineMatch if handled otherwise None.
258+
Optional[PipelineMatch]: A pipeline match if the stop intent is successfully processed,
259+
otherwise None if no stop intent is detected
260+
261+
Notes:
262+
- Attempts to match stop vocabulary with fuzzy matching
263+
- Falls back to low-confidence matching if medium-confidence match is inconclusive
264+
- Handles global stop scenarios when no active skills are present
195265
"""
196266
lang = self._get_closest_lang(lang)
197267
if lang is None: # no vocs registered for this lang
@@ -222,15 +292,24 @@ def _get_closest_lang(self, lang: str) -> Optional[str]:
222292
return None
223293

224294
def match_stop_low(self, utterances: List[str], lang: str, message: Message) -> Optional[PipelineMatch]:
225-
""" before fallback_low , fuzzy match stop intent
226-
227-
Args:
228-
utterances (list): list of utterances
229-
lang (string): 4 letter ISO language code
230-
message (Message): message to use to generate reply
231-
295+
"""
296+
Perform a low-confidence fuzzy match for stop intent before fallback processing.
297+
298+
This method attempts to match stop-related vocabulary with low confidence and handle stopping of active skills.
299+
300+
Parameters:
301+
utterances (List[str]): List of input utterances to match against stop vocabulary
302+
lang (str): Four-letter ISO language code for vocabulary matching
303+
message (Message): Message context used for generating replies and managing session
304+
232305
Returns:
233-
PipelineMatch if handled otherwise None.
306+
Optional[PipelineMatch]: A pipeline match object if a stop action is handled, otherwise None
307+
308+
Notes:
309+
- Increases confidence if active skills are present
310+
- Attempts to stop individual skills before emitting a global stop signal
311+
- Handles language-specific vocabulary matching
312+
- Configurable minimum confidence threshold for stop intent
234313
"""
235314
lang = self._get_closest_lang(lang)
236315
if lang is None: # no vocs registered for this lang

0 commit comments

Comments
 (0)