Expose the original speech sequence through pre_speech (#20775)
Closes #20766
Summary of the issue:
speech.speak applies filter_speechSequence before notifying pre_speech.
As a result, pre_speech handlers can only access the filtered speech sequence.
Speech filters may perform synthesis-specific and non-reversible transformations, such as splitting text or inserting speech commands.
Consumers that need the sequence originally passed to speech.speak cannot reliably reconstruct it from the filtered sequence.
Description of user facing changes:
There are no direct user-facing changes.
Description of developer facing changes:
The speech.extensions.pre_speech extension point now provides an originalSpeechSequence keyword argument containing the sequence passed to speech.speak before speech filters are applied.
The existing speechSequence argument remains the filtered sequence.
Handlers that only accept the existing arguments remain compatible.
Description of development approach:
A shallow copy of the speech sequence is made before applying filter_speechSequence.
The copy is passed to the existing pre_speech notification as originalSpeechSequence, while the filtered sequence continues to be passed as speechSequence.
The copy is made before filtering because filters may mutate the list in place.
A shallow copy is sufficient because speech command objects do not need to be duplicated.
This is related to #17429 and #16191.
Rather than adding separate pre-filter and post-filter actions, this change provides both representations through the existing pre_speech notification.
The post-filter action proposed in #17429 would duplicate the existing pre_speech extension point.
Providing both sequences in one notification also avoids consumers having to correlate separate notifications while preserving the existing notification timing and semantics.
The extension point documentation, Developer Guide, and change log have been updated.