utils: add match_endofsentence and use it in processors
This commit is contained in:
@@ -4,10 +4,9 @@
|
|||||||
# SPDX-License-Identifier: BSD 2-Clause License
|
# SPDX-License-Identifier: BSD 2-Clause License
|
||||||
#
|
#
|
||||||
|
|
||||||
import re
|
|
||||||
|
|
||||||
from pipecat.frames.frames import EndFrame, Frame, InterimTranscriptionFrame, TextFrame
|
from pipecat.frames.frames import EndFrame, Frame, InterimTranscriptionFrame, TextFrame
|
||||||
from pipecat.processors.frame_processor import FrameDirection, FrameProcessor
|
from pipecat.processors.frame_processor import FrameDirection, FrameProcessor
|
||||||
|
from pipecat.utils.string import match_endofsentence
|
||||||
|
|
||||||
|
|
||||||
class SentenceAggregator(FrameProcessor):
|
class SentenceAggregator(FrameProcessor):
|
||||||
@@ -40,12 +39,10 @@ class SentenceAggregator(FrameProcessor):
|
|||||||
return
|
return
|
||||||
|
|
||||||
if isinstance(frame, TextFrame):
|
if isinstance(frame, TextFrame):
|
||||||
m = re.search("(.*[?.!])(.*)", frame.text)
|
self._aggregation += frame.text
|
||||||
if m:
|
if match_endofsentence(self._aggregation):
|
||||||
await self.push_frame(TextFrame(self._aggregation + m.group(1)))
|
await self.push_frame(TextFrame(self._aggregation))
|
||||||
self._aggregation = m.group(2)
|
self._aggregation = ""
|
||||||
else:
|
|
||||||
self._aggregation += frame.text
|
|
||||||
elif isinstance(frame, EndFrame):
|
elif isinstance(frame, EndFrame):
|
||||||
if self._aggregation:
|
if self._aggregation:
|
||||||
await self.push_frame(TextFrame(self._aggregation))
|
await self.push_frame(TextFrame(self._aggregation))
|
||||||
|
|||||||
@@ -27,28 +27,10 @@ from pipecat.frames.frames import (
|
|||||||
from pipecat.processors.async_frame_processor import AsyncFrameProcessor
|
from pipecat.processors.async_frame_processor import AsyncFrameProcessor
|
||||||
from pipecat.processors.frame_processor import FrameDirection, FrameProcessor
|
from pipecat.processors.frame_processor import FrameDirection, FrameProcessor
|
||||||
from pipecat.utils.audio import calculate_audio_volume
|
from pipecat.utils.audio import calculate_audio_volume
|
||||||
|
from pipecat.utils.string import match_endofsentence
|
||||||
from pipecat.utils.utils import exp_smoothing
|
from pipecat.utils.utils import exp_smoothing
|
||||||
from pipecat.processors.aggregators.openai_llm_context import OpenAILLMContext
|
from pipecat.processors.aggregators.openai_llm_context import OpenAILLMContext
|
||||||
|
|
||||||
import re
|
|
||||||
|
|
||||||
|
|
||||||
ENDOFSENTENCE_PATTERN_STR = r"""
|
|
||||||
(?<![A-Z]) # Negative lookbehind: not preceded by an uppercase letter (e.g., "U.S.A.")
|
|
||||||
(?<!\d) # Negative lookbehind: not preceded by a digit (e.g., "1. Let's start")
|
|
||||||
(?<!\d\s[ap]) # Negative lookbehind: not preceded by time (e.g., "3:00 a.m.")
|
|
||||||
(?<!Mr|Ms|Dr) # Negative lookbehind: not preceded by Mr, Ms, Dr (combined bc. length is the same)
|
|
||||||
(?<!Mrs) # Negative lookbehind: not preceded by "Mrs"
|
|
||||||
(?<!Prof) # Negative lookbehind: not preceded by "Prof"
|
|
||||||
[\.\?\!:] # Match a period, question mark, exclamation point, or colon
|
|
||||||
$ # End of string
|
|
||||||
"""
|
|
||||||
ENDOFSENTENCE_PATTERN = re.compile(ENDOFSENTENCE_PATTERN_STR, re.VERBOSE)
|
|
||||||
|
|
||||||
|
|
||||||
def match_endofsentence(text: str) -> bool:
|
|
||||||
return ENDOFSENTENCE_PATTERN.search(text.rstrip()) is not None
|
|
||||||
|
|
||||||
|
|
||||||
class AIService(FrameProcessor):
|
class AIService(FrameProcessor):
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
|
|||||||
24
src/pipecat/utils/string.py
Normal file
24
src/pipecat/utils/string.py
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#
|
||||||
|
# Copyright (c) 2024, Daily
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: BSD 2-Clause License
|
||||||
|
#
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
|
ENDOFSENTENCE_PATTERN_STR = r"""
|
||||||
|
(?<![A-Z]) # Negative lookbehind: not preceded by an uppercase letter (e.g., "U.S.A.")
|
||||||
|
(?<!\d) # Negative lookbehind: not preceded by a digit (e.g., "1. Let's start")
|
||||||
|
(?<!\d\s[ap]) # Negative lookbehind: not preceded by time (e.g., "3:00 a.m.")
|
||||||
|
(?<!Mr|Ms|Dr) # Negative lookbehind: not preceded by Mr, Ms, Dr (combined bc. length is the same)
|
||||||
|
(?<!Mrs) # Negative lookbehind: not preceded by "Mrs"
|
||||||
|
(?<!Prof) # Negative lookbehind: not preceded by "Prof"
|
||||||
|
[\.\?\!:] # Match a period, question mark, exclamation point, or colon
|
||||||
|
$ # End of string
|
||||||
|
"""
|
||||||
|
ENDOFSENTENCE_PATTERN = re.compile(ENDOFSENTENCE_PATTERN_STR, re.VERBOSE)
|
||||||
|
|
||||||
|
|
||||||
|
def match_endofsentence(text: str) -> bool:
|
||||||
|
return ENDOFSENTENCE_PATTERN.search(text.rstrip()) is not None
|
||||||
Reference in New Issue
Block a user