PipelineTask: set finished_event InterruptionFrame is received

This commit is contained in:
Aleix Conchillo Flaqué
2025-10-10 20:27:24 -07:00
parent a1c07039ee
commit c33b81bb92
3 changed files with 13 additions and 4 deletions

View File

@@ -9,6 +9,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Added an asyncio event `finished_event` field to `InterruptionFrame`. When
assigned, the asyncio event will be set when the frame reaches the end of the
pipeline. You can use this field to know when an interruption made it all the
way to the end of a pipeline. The field has been also added to
`InterruptionTaskFrame`.
- Added support for loading external observers. You can now register custom
pipeline observers by setting the `PIPECAT_OBSERVER_FILES` environment
variable. This variable should contain a colon-separated list of Python files
@@ -28,8 +34,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `CancelFrame` and `CancelTaskFrame` have an optional `reason` field to
indicate why the pipeline is being canceled. This can be also specified when
you cancel a task with `PipelineTask.cancel(reason="cancellation your
reason")`.
you cancel a task with `PipelineTask.cancel(reason="cancellation reason")`.
- Added `include_prob_metrics` parameter to Whisper STT services to enable access
to probability metrics from transcription results.

View File

@@ -862,7 +862,7 @@ class InterruptionFrame(SystemFrame):
with other frames (so the order is not guaranteed).
Parameters:
wait_event: If not None, the event will be set when the frame
finished_event: If not None, the event will be set when the frame
reaches the end of the pipeline.
"""

View File

@@ -745,7 +745,7 @@ class PipelineTask(BasePipelineTask):
# pipeline. This is in case the push task is blocked waiting for a
# pipeline-ending frame to finish traversing the pipeline.
logger.debug(f"{self}: received interruption task frame {frame}")
await self._pipeline.queue_frame(InterruptionFrame())
await self._pipeline.queue_frame(InterruptionFrame(finished_event=frame.finished_event))
elif isinstance(frame, ErrorFrame):
await self._call_event_handler("on_pipeline_error", frame)
if frame.fatal:
@@ -786,6 +786,10 @@ class PipelineTask(BasePipelineTask):
self._pipeline_end_event.set()
elif isinstance(frame, HeartbeatFrame):
await self._heartbeat_queue.put(frame)
elif isinstance(frame, InterruptionFrame) and frame.finished_event:
# This should unblock any code waiting for the interruption to
# complete.
frame.finished_event.set()
async def _heartbeat_push_handler(self):
"""Push heartbeat frames at regular intervals."""