From c6a18378441eacddd18393abd9b60940617bf1b1 Mon Sep 17 00:00:00 2001 From: Mark Backman Date: Thu, 16 Apr 2026 21:22:46 -0400 Subject: [PATCH] Fix type errors in extensions and add to pyright checked set Tighten LLMMessagesAppendFrame and LLMMessagesUpdateFrame message fields from list[dict] to list[LLMContextMessage] to match actual usage. Add type annotations on inline message lists in IVR navigator and voicemail detector. --- pyrightconfig.json | 3 ++- src/pipecat/extensions/ivr/ivr_navigator.py | 15 +++++++++------ .../extensions/voicemail/voicemail_detector.py | 6 +++--- src/pipecat/frames/frames.py | 9 ++++----- 4 files changed, 18 insertions(+), 15 deletions(-) diff --git a/pyrightconfig.json b/pyrightconfig.json index 69d2ba8db..ea03dc37b 100644 --- a/pyrightconfig.json +++ b/pyrightconfig.json @@ -7,7 +7,8 @@ "src/pipecat/metrics", "src/pipecat/transcriptions", "src/pipecat/frames", - "src/pipecat/observers" + "src/pipecat/observers", + "src/pipecat/extensions" ], "exclude": [ "**/*_pb2.py", diff --git a/src/pipecat/extensions/ivr/ivr_navigator.py b/src/pipecat/extensions/ivr/ivr_navigator.py index f6b36655b..37b2469bb 100644 --- a/src/pipecat/extensions/ivr/ivr_navigator.py +++ b/src/pipecat/extensions/ivr/ivr_navigator.py @@ -30,6 +30,7 @@ from pipecat.frames.frames import ( VADParamsUpdateFrame, ) from pipecat.pipeline.pipeline import Pipeline +from pipecat.processors.aggregators.llm_context import LLMContextMessage from pipecat.processors.frame_processor import FrameDirection, FrameProcessor from pipecat.services.llm_service import LLMService from pipecat.utils.text.pattern_pair_aggregator import ( @@ -87,7 +88,7 @@ class IVRProcessor(FrameProcessor): self._classifier_prompt = classifier_prompt # Store saved context messages - self._saved_messages: list[dict] = [] + self._saved_messages: list[LLMContextMessage] = [] # XML pattern aggregation self._aggregator = PatternPairAggregator() @@ -97,18 +98,18 @@ class IVRProcessor(FrameProcessor): self._register_event_handler("on_conversation_detected") self._register_event_handler("on_ivr_status_changed") - def update_saved_messages(self, messages: list[dict]) -> None: + def update_saved_messages(self, messages: list[LLMContextMessage]) -> None: """Update the saved context messages. Sets the messages that are saved when switching between conversation and IVR navigation modes. Args: - messages: List of message dictionaries to save. + messages: List of context messages to save. """ self._saved_messages = messages - def _get_conversation_history(self) -> list[dict]: + def _get_conversation_history(self) -> list[LLMContextMessage]: """Get saved context messages without the system message. Returns: @@ -144,7 +145,9 @@ class IVRProcessor(FrameProcessor): await self.push_frame(frame, direction) # Set the classifier prompt and push it upstream - messages = [{"role": "system", "content": self._classifier_prompt}] + messages: list[LLMContextMessage] = [ + {"role": "developer", "content": self._classifier_prompt} + ] llm_update_frame = LLMMessagesUpdateFrame(messages=messages) await self.push_frame(llm_update_frame, FrameDirection.UPSTREAM) @@ -261,7 +264,7 @@ class IVRProcessor(FrameProcessor): logger.debug("IVR detected - switching to IVR navigation mode") # Create new context with IVR system prompt and saved messages - messages = [{"role": "system", "content": self._ivr_prompt}] + messages: list[LLMContextMessage] = [{"role": "developer", "content": self._ivr_prompt}] # Add saved conversation history if available conversation_history = self._get_conversation_history() diff --git a/src/pipecat/extensions/voicemail/voicemail_detector.py b/src/pipecat/extensions/voicemail/voicemail_detector.py index 3ab7f2f7d..d7e9d559b 100644 --- a/src/pipecat/extensions/voicemail/voicemail_detector.py +++ b/src/pipecat/extensions/voicemail/voicemail_detector.py @@ -35,7 +35,7 @@ from pipecat.frames.frames import ( UserStoppedSpeakingFrame, ) from pipecat.pipeline.parallel_pipeline import ParallelPipeline -from pipecat.processors.aggregators.llm_context import LLMContext +from pipecat.processors.aggregators.llm_context import LLMContext, LLMContextMessage from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, LLMUserAggregatorParams, @@ -617,9 +617,9 @@ VOICEMAIL SYSTEM (respond "VOICEMAIL"): self._validate_prompt(custom_system_prompt) # Set up the LLM context with the classification prompt - self._messages = [ + self._messages: list[LLMContextMessage] = [ { - "role": "system", + "role": "developer", "content": self._prompt, }, ] diff --git a/src/pipecat/frames/frames.py b/src/pipecat/frames/frames.py index 7fd215caf..24006428d 100644 --- a/src/pipecat/frames/frames.py +++ b/src/pipecat/frames/frames.py @@ -20,7 +20,6 @@ from typing import ( TYPE_CHECKING, Any, Literal, - Optional, ) from pipecat.adapters.schemas.tools_schema import ToolsSchema @@ -559,11 +558,11 @@ class LLMMessagesAppendFrame(DataFrame): current context. Parameters: - messages: List of message dictionaries to append. + messages: List of context messages to append. run_llm: Whether the context update should be sent to the LLM. """ - messages: list[dict] + messages: list[LLMContextMessage] run_llm: bool | None = None @@ -575,11 +574,11 @@ class LLMMessagesUpdateFrame(DataFrame): context LLM messages. Parameters: - messages: List of message dictionaries to replace current context. + messages: List of context messages to replace current context. run_llm: Whether the context update should be sent to the LLM. """ - messages: list[dict] + messages: list[LLMContextMessage] run_llm: bool | None = None