Add LLMRunFrame to trigger an LLM response, replacing context_aggregator.user().get_context_frame()

This commit is contained in:
Paul Kompfner
2025-08-26 16:39:23 -04:00
parent e384ca949e
commit 189749b579
123 changed files with 331 additions and 163 deletions

View File

@@ -537,6 +537,17 @@ class LLMMessagesFrame(DataFrame):
)
@dataclass
class LLMRunFrame(DataFrame):
"""Frame to trigger LLM processing with current context.
A frame that instructs the LLM service to process the current context and
generate a response.
"""
pass
@dataclass
class LLMMessagesAppendFrame(DataFrame):
"""Frame containing LLM messages to append to current context.
@@ -557,9 +568,8 @@ class LLMMessagesAppendFrame(DataFrame):
class LLMMessagesUpdateFrame(DataFrame):
"""Frame containing LLM messages to replace current context.
A frame containing a list of new LLM messages. These messages will
replace the current context LLM messages and should generate a new
LLMMessagesFrame.
A frame containing a list of new LLM messages to replace the current
context LLM messages.
Parameters:
messages: List of message dictionaries to replace current context.

View File

@@ -42,6 +42,7 @@ from pipecat.frames.frames import (
LLMMessagesAppendFrame,
LLMMessagesFrame,
LLMMessagesUpdateFrame,
LLMRunFrame,
LLMSetToolChoiceFrame,
LLMSetToolsFrame,
LLMTextFrame,
@@ -319,9 +320,20 @@ class LLMContextResponseAggregator(BaseLLMResponseAggregator):
def get_context_frame(self) -> OpenAILLMContextFrame:
"""Create a context frame with the current context.
.. deprecated:: 0.0.82
This method is deprecated and will be removed in a future version.
Returns:
OpenAILLMContextFrame containing the current context.
LLMContextFrame containing the current context.
"""
warnings.warn(
"get_context_frame() is deprecated and will be removed in a future version. To trigger an LLM response, use LLMRunFrame instead.",
DeprecationWarning,
stacklevel=2,
)
return self._get_context_frame()
def _get_context_frame(self) -> OpenAILLMContextFrame:
return OpenAILLMContextFrame(context=self._context)
async def push_context_frame(self, direction: FrameDirection = FrameDirection.DOWNSTREAM):
@@ -330,7 +342,7 @@ class LLMContextResponseAggregator(BaseLLMResponseAggregator):
Args:
direction: The direction to push the frame (upstream or downstream).
"""
frame = self.get_context_frame()
frame = self._get_context_frame()
await self.push_frame(frame, direction)
def add_messages(self, messages):
@@ -484,6 +496,8 @@ class LLMUserContextAggregator(LLMContextResponseAggregator):
await self._handle_transcription(frame)
elif isinstance(frame, InterimTranscriptionFrame):
await self._handle_interim_transcription(frame)
elif isinstance(frame, LLMRunFrame):
await self._handle_llm_run(frame)
elif isinstance(frame, LLMMessagesAppendFrame):
await self._handle_llm_messages_append(frame)
elif isinstance(frame, LLMMessagesUpdateFrame):
@@ -563,6 +577,9 @@ class LLMUserContextAggregator(LLMContextResponseAggregator):
async def _cancel(self, frame: CancelFrame):
await self._cancel_aggregation_task()
async def _handle_llm_run(self, frame: LLMRunFrame):
await self.push_context_frame()
async def _handle_llm_messages_append(self, frame: LLMMessagesAppendFrame):
self.add_messages(frame.messages)
if frame.run_llm:
@@ -827,6 +844,8 @@ class LLMAssistantContextAggregator(LLMContextResponseAggregator):
await self._handle_llm_end(frame)
elif isinstance(frame, TextFrame):
await self._handle_text(frame)
elif isinstance(frame, LLMRunFrame):
await self._handle_llm_run(frame)
elif isinstance(frame, LLMMessagesAppendFrame):
await self._handle_llm_messages_append(frame)
elif isinstance(frame, LLMMessagesUpdateFrame):
@@ -869,6 +888,9 @@ class LLMAssistantContextAggregator(LLMContextResponseAggregator):
timestamp_frame = OpenAILLMContextAssistantTimestampFrame(timestamp=time_now_iso8601())
await self.push_frame(timestamp_frame)
async def _handle_llm_run(self, frame: LLMRunFrame):
await self.push_context_frame(FrameDirection.UPSTREAM)
async def _handle_llm_messages_append(self, frame: LLMMessagesAppendFrame):
self.add_messages(frame.messages)
if frame.run_llm:

View File

@@ -43,6 +43,7 @@ from pipecat.frames.frames import (
LLMFullResponseStartFrame,
LLMMessagesAppendFrame,
LLMMessagesUpdateFrame,
LLMRunFrame,
LLMSetToolChoiceFrame,
LLMSetToolsFrame,
SpeechControlParamsFrame,
@@ -117,7 +118,7 @@ class LLMContextAggregator(FrameProcessor):
"""
return self._context
def get_context_frame(self) -> LLMContextFrame:
def _get_context_frame(self) -> LLMContextFrame:
"""Create a context frame with the current context.
Returns:
@@ -131,7 +132,7 @@ class LLMContextAggregator(FrameProcessor):
Args:
direction: The direction to push the frame (upstream or downstream).
"""
frame = self.get_context_frame()
frame = self._get_context_frame()
await self.push_frame(frame, direction)
def add_messages(self, messages):
@@ -277,6 +278,8 @@ class LLMUserAggregator(LLMContextAggregator):
await self._handle_transcription(frame)
elif isinstance(frame, InterimTranscriptionFrame):
await self._handle_interim_transcription(frame)
elif isinstance(frame, LLMRunFrame):
await self._handle_llm_run(frame)
elif isinstance(frame, LLMMessagesAppendFrame):
await self._handle_llm_messages_append(frame)
elif isinstance(frame, LLMMessagesUpdateFrame):
@@ -356,6 +359,9 @@ class LLMUserAggregator(LLMContextAggregator):
async def _cancel(self, frame: CancelFrame):
await self._cancel_aggregation_task()
async def _handle_llm_run(self, frame: LLMRunFrame):
await self.push_context_frame()
async def _handle_llm_messages_append(self, frame: LLMMessagesAppendFrame):
self.add_messages(frame.messages)
if frame.run_llm:
@@ -582,6 +588,8 @@ class LLMAssistantAggregator(LLMContextAggregator):
await self._handle_llm_end(frame)
elif isinstance(frame, TextFrame):
await self._handle_text(frame)
elif isinstance(frame, LLMRunFrame):
await self._handle_llm_run(frame)
elif isinstance(frame, LLMMessagesAppendFrame):
await self._handle_llm_messages_append(frame)
elif isinstance(frame, LLMMessagesUpdateFrame):
@@ -624,6 +632,9 @@ class LLMAssistantAggregator(LLMContextAggregator):
timestamp_frame = LLMContextAssistantTimestampFrame(timestamp=time_now_iso8601())
await self.push_frame(timestamp_frame)
async def _handle_llm_run(self, frame: LLMRunFrame):
await self.push_context_frame(FrameDirection.UPSTREAM)
async def _handle_llm_messages_append(self, frame: LLMMessagesAppendFrame):
self.add_messages(frame.messages)
if frame.run_llm: