Skip to content

Commit a0da0a5

Browse files
committed
Support customization over the way the assistant aggregator aggregates LLMTextFrames when tts_skip is on
1 parent ca3a823 commit a0da0a5

File tree

2 files changed

+20
-18
lines changed

2 files changed

+20
-18
lines changed

src/pipecat/processors/aggregators/llm_response.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
OpenAILLMContextFrame,
6060
)
6161
from pipecat.processors.frame_processor import FrameDirection, FrameProcessor
62+
from pipecat.utils.text.base_text_aggregator import BaseTextAggregator
6263
from pipecat.utils.time import time_now_iso8601
6364

6465

@@ -95,6 +96,7 @@ class LLMAssistantAggregatorParams:
9596
"""
9697

9798
expect_stripped_words: bool = True
99+
llm_text_aggregator: Optional[BaseTextAggregator] = None
98100

99101

100102
class LLMFullResponseAggregator(FrameProcessor):

src/pipecat/processors/aggregators/llm_response_universal.py

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,9 @@
6868
LLMUserAggregatorParams,
6969
)
7070
from pipecat.processors.frame_processor import FrameDirection, FrameProcessor
71-
from pipecat.utils.string import concatenate_aggregated_text, match_endofsentence
71+
from pipecat.utils.string import concatenate_aggregated_text
72+
from pipecat.utils.text.base_text_aggregator import BaseTextAggregator
73+
from pipecat.utils.text.simple_text_aggregator import SimpleTextAggregator
7274
from pipecat.utils.time import time_now_iso8601
7375

7476

@@ -589,7 +591,9 @@ def __init__(
589591
self._function_calls_in_progress: Dict[str, Optional[FunctionCallInProgressFrame]] = {}
590592
self._context_updated_tasks: Set[asyncio.Task] = set()
591593

592-
self._llm_aggregation: str = ""
594+
self._llm_text_aggregator: BaseTextAggregator = (
595+
self._params.llm_text_aggregator or SimpleTextAggregator()
596+
)
593597
self._skip_tts: Optional[bool] = None
594598

595599
@property
@@ -813,8 +817,6 @@ async def _handle_llm_start(self, frame: LLMFullResponseStartFrame):
813817

814818
async def _handle_llm_text(self, frame: LLMTextFrame):
815819
await self._handle_text(frame)
816-
if self._skip_tts or frame.skip_tts:
817-
self._llm_aggregation += frame.text
818820
await self._maybe_push_llm_aggregation(frame)
819821

820822
async def _handle_llm_end(self, frame: LLMFullResponseEndFrame):
@@ -825,30 +827,28 @@ async def _handle_llm_end(self, frame: LLMFullResponseEndFrame):
825827
async def _maybe_push_llm_aggregation(
826828
self, frame: LLMFullResponseStartFrame | LLMTextFrame | LLMFullResponseEndFrame
827829
):
828-
should_push = False
830+
aggregate = None
831+
should_reset_aggregator = False
829832
if self._skip_tts and not frame.skip_tts:
830833
# if the skip_tts flag switches, to false, push the current aggregation
831-
should_push = True
834+
aggregate = self._llm_text_aggregator.text
835+
should_reset_aggregator = True
832836
self._skip_tts = frame.skip_tts
833837
if self._skip_tts:
834838
if self._skip_tts and isinstance(frame, LLMFullResponseEndFrame):
835839
# on end frame, always push the aggregation
836-
should_push = True
837-
elif len(self._llm_aggregation) > 0 and match_endofsentence(self._llm_aggregation):
838-
# push aggregation on end of sentence
839-
should_push = True
840-
841-
if not should_push:
842-
return
840+
aggregate = self._llm_text_aggregator.text
841+
should_reset_aggregator = True
842+
elif isinstance(frame, LLMTextFrame):
843+
aggregate = await self._llm_text_aggregator.aggregate(frame.text)
843844

844-
text = self._llm_aggregation.lstrip("\n")
845-
if not text.strip():
846-
# don't push empty text
845+
if not aggregate:
847846
return
848847

849-
llm_frame = AggregatedLLMTextFrame(text=text, aggregated_by="sentence")
848+
llm_frame = AggregatedLLMTextFrame(text=aggregate.text, aggregated_by=aggregate.type)
850849
await self.push_frame(llm_frame)
851-
self._llm_aggregation = ""
850+
if should_reset_aggregator:
851+
await self._llm_text_aggregator.reset()
852852

853853
async def _handle_text(self, frame: TextFrame):
854854
if not self._started or not frame.append_to_context:

0 commit comments

Comments
 (0)