diff --git a/examples/foundational/07m-interruptible-aws-strands.py b/examples/foundational/07m-interruptible-aws-strands.py index eca2947fc..934215fbb 100644 --- a/examples/foundational/07m-interruptible-aws-strands.py +++ b/examples/foundational/07m-interruptible-aws-strands.py @@ -9,14 +9,12 @@ from dotenv import load_dotenv from loguru import logger from pipecat.audio.vad.silero import SileroVADAnalyzer +from pipecat.frames.frames import LLMMessagesAppendFrame, LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner from pipecat.pipeline.task import PipelineParams, PipelineTask -from pipecat.processors.aggregators.llm_response import ( - LLMAssistantContextAggregator, - LLMUserContextAggregator, -) -from pipecat.processors.aggregators.openai_llm_context import OpenAILLMContext +from pipecat.processors.aggregators.llm_context import LLMContext +from pipecat.processors.aggregators.llm_response_universal import LLMContextAggregatorPair from pipecat.processors.frameworks.strands_agents import StrandsAgentsProcessor from pipecat.runner.types import RunnerArguments from pipecat.runner.utils import create_transport @@ -115,19 +113,18 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ) # Setup context aggregators for message handling - context = OpenAILLMContext() - tma_in = LLMUserContextAggregator(context=context) - tma_out = LLMAssistantContextAggregator(context=context) + context = LLMContext() + context_aggregator = LLMContextAggregatorPair(context) pipeline = Pipeline( [ transport.input(), # Transport user input stt, # Speech-to-text - tma_in, # User context aggregator + context_aggregator.user(), # User responses llm, # Strands Agents processor tts, # Text-to-speech transport.output(), # Transport bot output - tma_out, # Assistant context aggregator + context_aggregator.assistant(), # Assistant spoken responses ] ) @@ -143,6 +140,20 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_connected") async def on_client_connected(transport, client): logger.info(f"Client connected") + # Kick off the conversation. + await task.queue_frames( + [ + LLMMessagesAppendFrame( + messages=[ + { + "role": "user", + "content": f"Greet the user and introduce yourself.", + } + ], + run_llm=True, + ) + ] + ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): diff --git a/scripts/evals/run-release-evals.py b/scripts/evals/run-release-evals.py index f17a7f6fa..1079df1ee 100644 --- a/scripts/evals/run-release-evals.py +++ b/scripts/evals/run-release-evals.py @@ -83,6 +83,7 @@ TESTS_07 = [ ("07k-interruptible-lmnt.py", PROMPT_SIMPLE_MATH, EVAL_SIMPLE_MATH, BOT_SPEAKS_FIRST), ("07l-interruptible-groq.py", PROMPT_SIMPLE_MATH, EVAL_SIMPLE_MATH, BOT_SPEAKS_FIRST), ("07m-interruptible-aws.py", PROMPT_SIMPLE_MATH, EVAL_SIMPLE_MATH, BOT_SPEAKS_FIRST), + ("07m-interruptible-aws-strands.py", PROMPT_WEATHER, EVAL_WEATHER, BOT_SPEAKS_FIRST), ("07n-interruptible-gemini.py", PROMPT_SIMPLE_MATH, EVAL_SIMPLE_MATH, BOT_SPEAKS_FIRST), ("07n-interruptible-google.py", PROMPT_SIMPLE_MATH, EVAL_SIMPLE_MATH, BOT_SPEAKS_FIRST), ("07o-interruptible-assemblyai.py", PROMPT_SIMPLE_MATH, EVAL_SIMPLE_MATH, BOT_SPEAKS_FIRST), diff --git a/src/pipecat/processors/frameworks/strands_agents.py b/src/pipecat/processors/frameworks/strands_agents.py index d129c2063..829c799ac 100644 --- a/src/pipecat/processors/frameworks/strands_agents.py +++ b/src/pipecat/processors/frameworks/strands_agents.py @@ -10,12 +10,12 @@ from loguru import logger from pipecat.frames.frames import ( Frame, + LLMContextFrame, LLMFullResponseEndFrame, LLMFullResponseStartFrame, LLMTextFrame, ) from pipecat.metrics.metrics import LLMTokenUsage -from pipecat.processors.aggregators.openai_llm_context import OpenAILLMContextFrame from pipecat.processors.frame_processor import FrameDirection, FrameProcessor try: @@ -71,9 +71,11 @@ class StrandsAgentsProcessor(FrameProcessor): direction: The direction of frame flow in the pipeline. """ await super().process_frame(frame, direction) - if isinstance(frame, OpenAILLMContextFrame): - text = frame.context.messages[-1]["content"] - await self._ainvoke(str(text).strip()) + if isinstance(frame, LLMContextFrame): + messages = frame.context.get_messages() + if messages: + last_message = messages[-1] + await self._ainvoke(str(last_message["content"]).strip()) else: await self.push_frame(frame, direction)