From 457eb7aa9260f5d1292d59fb201a478927a25c72 Mon Sep 17 00:00:00 2001 From: Mark Backman Date: Wed, 22 Apr 2026 11:19:23 -0400 Subject: [PATCH] Mark abstract image/vision generators as real async generators `ImageGenService.run_image_gen` and `VisionService.run_vision` were declared `async def ... -> AsyncGenerator[Frame, None]` with `pass` bodies. Without a `yield` anywhere in the body, Python treats the function as a coroutine returning an `AsyncGenerator`, not as an async generator itself, so callers got a coroutine where they expected an iterator. Add `raise NotImplementedError; yield` so the body contains a yield (making this a real async generator) while still raising cleanly if a subclass ever calls `super().run_*` by mistake. --- pyrightconfig.json | 2 -- src/pipecat/services/image_service.py | 3 ++- src/pipecat/services/vision_service.py | 3 ++- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pyrightconfig.json b/pyrightconfig.json index 883c7276a..0f10db1b6 100644 --- a/pyrightconfig.json +++ b/pyrightconfig.json @@ -76,7 +76,6 @@ "src/pipecat/services/heygen/client.py", "src/pipecat/services/heygen/video.py", "src/pipecat/services/hume/tts.py", - "src/pipecat/services/image_service.py", "src/pipecat/services/inworld/realtime/llm.py", "src/pipecat/services/inworld/tts.py", "src/pipecat/services/kokoro/tts.py", @@ -115,7 +114,6 @@ "src/pipecat/services/tavus/video.py", "src/pipecat/services/tts_service.py", "src/pipecat/services/ultravox/llm.py", - "src/pipecat/services/vision_service.py", "src/pipecat/services/websocket_service.py", "src/pipecat/services/whisper/stt.py", "src/pipecat/services/xai/realtime/events.py", diff --git a/src/pipecat/services/image_service.py b/src/pipecat/services/image_service.py index df8ef66fe..28ab8d98b 100644 --- a/src/pipecat/services/image_service.py +++ b/src/pipecat/services/image_service.py @@ -57,7 +57,8 @@ class ImageGenService(AIService): Frame: Frames containing the generated image (typically ImageRawFrame or URLImageRawFrame). """ - pass + raise NotImplementedError + yield # pragma: no cover async def process_frame(self, frame: Frame, direction: FrameDirection): """Process frames for image generation. diff --git a/src/pipecat/services/vision_service.py b/src/pipecat/services/vision_service.py index 74d70f1d4..22e528042 100644 --- a/src/pipecat/services/vision_service.py +++ b/src/pipecat/services/vision_service.py @@ -59,7 +59,8 @@ class VisionService(AIService): Frame: Frames containing the vision analysis results, typically TextFrame objects with descriptions or answers. """ - pass + raise NotImplementedError + yield # pragma: no cover async def process_frame(self, frame: Frame, direction: FrameDirection): """Process frames, handling vision image frames for analysis.