turns: rename bot turn start to user turn stop strategies

This commit is contained in:
Aleix Conchillo Flaqué
2025-12-30 14:09:00 -08:00
parent fb9a772e33
commit eb5a797b12
161 changed files with 921 additions and 891 deletions

View File

@@ -15,25 +15,24 @@ from pipecat.frames.frames import (
VADUserStartedSpeakingFrame,
VADUserStoppedSpeakingFrame,
)
from pipecat.turns.bot import TranscriptionBotTurnStartStrategy
from pipecat.turns.bot.external_bot_turn_start_strategy import ExternalBotTurnStartStrategy
from pipecat.turns.user_stop import ExternalUserTurnStopStrategy, TranscriptionUserTurnStopStrategy
from pipecat.utils.asyncio.task_manager import TaskManager, TaskManagerParams
AGGREGATION_TIMEOUT = 0.1
class TestTranscriptionBotTurnStartStrategy(unittest.IsolatedAsyncioTestCase):
class TestTranscriptionUserTurnStopStrategy(unittest.IsolatedAsyncioTestCase):
async def asyncSetUp(self) -> None:
self.task_manager = TaskManager()
self.task_manager.setup(TaskManagerParams(loop=asyncio.get_running_loop()))
async def test_ste(self):
strategy = TranscriptionBotTurnStartStrategy()
strategy = TranscriptionUserTurnStopStrategy()
should_start = None
@strategy.event_handler("on_bot_turn_started")
async def on_bot_turn_started(strategy, params):
@strategy.event_handler("on_user_turn_stopped")
async def on_user_turn_stopped(strategy, params):
nonlocal should_start
should_start = True
@@ -53,12 +52,12 @@ class TestTranscriptionBotTurnStartStrategy(unittest.IsolatedAsyncioTestCase):
self.assertTrue(should_start)
async def test_site(self):
strategy = TranscriptionBotTurnStartStrategy()
strategy = TranscriptionUserTurnStopStrategy()
should_start = None
@strategy.event_handler("on_bot_turn_started")
async def on_bot_turn_started(strategy, params):
@strategy.event_handler("on_user_turn_stopped")
async def on_user_turn_stopped(strategy, params):
nonlocal should_start
should_start = True
@@ -84,12 +83,12 @@ class TestTranscriptionBotTurnStartStrategy(unittest.IsolatedAsyncioTestCase):
self.assertTrue(should_start)
async def test_st1iest2e(self):
strategy = TranscriptionBotTurnStartStrategy()
strategy = TranscriptionUserTurnStopStrategy()
should_start = None
@strategy.event_handler("on_bot_turn_started")
async def on_bot_turn_started(strategy, params):
@strategy.event_handler("on_user_turn_stopped")
async def on_user_turn_stopped(strategy, params):
nonlocal should_start
should_start = True
@@ -130,13 +129,13 @@ class TestTranscriptionBotTurnStartStrategy(unittest.IsolatedAsyncioTestCase):
self.assertTrue(should_start)
async def test_siet(self):
strategy = TranscriptionBotTurnStartStrategy(timeout=AGGREGATION_TIMEOUT)
strategy = TranscriptionUserTurnStopStrategy(timeout=AGGREGATION_TIMEOUT)
await strategy.setup(self.task_manager)
should_start = None
@strategy.event_handler("on_bot_turn_started")
async def on_bot_turn_started(strategy, params):
@strategy.event_handler("on_user_turn_stopped")
async def on_user_turn_stopped(strategy, params):
nonlocal should_start
should_start = True
@@ -164,13 +163,13 @@ class TestTranscriptionBotTurnStartStrategy(unittest.IsolatedAsyncioTestCase):
self.assertTrue(should_start)
async def test_sieit(self):
strategy = TranscriptionBotTurnStartStrategy(timeout=AGGREGATION_TIMEOUT)
strategy = TranscriptionUserTurnStopStrategy(timeout=AGGREGATION_TIMEOUT)
await strategy.setup(self.task_manager)
should_start = None
@strategy.event_handler("on_bot_turn_started")
async def on_bot_turn_started(strategy, params):
@strategy.event_handler("on_user_turn_stopped")
async def on_user_turn_stopped(strategy, params):
nonlocal should_start
should_start = True
@@ -206,13 +205,13 @@ class TestTranscriptionBotTurnStartStrategy(unittest.IsolatedAsyncioTestCase):
self.assertTrue(should_start)
async def test_set(self):
strategy = TranscriptionBotTurnStartStrategy(timeout=AGGREGATION_TIMEOUT)
strategy = TranscriptionUserTurnStopStrategy(timeout=AGGREGATION_TIMEOUT)
await strategy.setup(self.task_manager)
should_start = None
@strategy.event_handler("on_bot_turn_started")
async def on_bot_turn_started(strategy, params):
@strategy.event_handler("on_user_turn_stopped")
async def on_user_turn_stopped(strategy, params):
nonlocal should_start
should_start = True
@@ -236,13 +235,13 @@ class TestTranscriptionBotTurnStartStrategy(unittest.IsolatedAsyncioTestCase):
self.assertTrue(should_start)
async def test_seit(self):
strategy = TranscriptionBotTurnStartStrategy(timeout=AGGREGATION_TIMEOUT)
strategy = TranscriptionUserTurnStopStrategy(timeout=AGGREGATION_TIMEOUT)
await strategy.setup(self.task_manager)
should_start = None
@strategy.event_handler("on_bot_turn_started")
async def on_bot_turn_started(strategy, params):
@strategy.event_handler("on_user_turn_stopped")
async def on_user_turn_stopped(strategy, params):
nonlocal should_start
should_start = True
@@ -272,13 +271,13 @@ class TestTranscriptionBotTurnStartStrategy(unittest.IsolatedAsyncioTestCase):
self.assertTrue(should_start)
async def test_st1et2(self):
strategy = TranscriptionBotTurnStartStrategy(timeout=AGGREGATION_TIMEOUT)
strategy = TranscriptionUserTurnStopStrategy(timeout=AGGREGATION_TIMEOUT)
await strategy.setup(self.task_manager)
should_start = None
@strategy.event_handler("on_bot_turn_started")
async def on_bot_turn_started(strategy, params):
@strategy.event_handler("on_user_turn_stopped")
async def on_user_turn_stopped(strategy, params):
nonlocal should_start
should_start = True
@@ -310,13 +309,13 @@ class TestTranscriptionBotTurnStartStrategy(unittest.IsolatedAsyncioTestCase):
self.assertTrue(should_start)
async def test_set1t2(self):
strategy = TranscriptionBotTurnStartStrategy(timeout=AGGREGATION_TIMEOUT)
strategy = TranscriptionUserTurnStopStrategy(timeout=AGGREGATION_TIMEOUT)
await strategy.setup(self.task_manager)
should_start = None
@strategy.event_handler("on_bot_turn_started")
async def on_bot_turn_started(strategy, params):
@strategy.event_handler("on_user_turn_stopped")
async def on_user_turn_stopped(strategy, params):
nonlocal should_start
should_start = True
@@ -344,13 +343,13 @@ class TestTranscriptionBotTurnStartStrategy(unittest.IsolatedAsyncioTestCase):
self.assertTrue(should_start)
async def test_siet1it2(self):
strategy = TranscriptionBotTurnStartStrategy(timeout=AGGREGATION_TIMEOUT)
strategy = TranscriptionUserTurnStopStrategy(timeout=AGGREGATION_TIMEOUT)
await strategy.setup(self.task_manager)
should_start = None
@strategy.event_handler("on_bot_turn_started")
async def on_bot_turn_started(strategy, params):
@strategy.event_handler("on_user_turn_stopped")
async def on_user_turn_stopped(strategy, params):
nonlocal should_start
should_start = True
@@ -389,13 +388,13 @@ class TestTranscriptionBotTurnStartStrategy(unittest.IsolatedAsyncioTestCase):
self.assertTrue(should_start)
async def test_t(self):
strategy = TranscriptionBotTurnStartStrategy(timeout=AGGREGATION_TIMEOUT)
strategy = TranscriptionUserTurnStopStrategy(timeout=AGGREGATION_TIMEOUT)
await strategy.setup(self.task_manager)
should_start = None
@strategy.event_handler("on_bot_turn_started")
async def on_bot_turn_started(strategy, params):
@strategy.event_handler("on_user_turn_stopped")
async def on_user_turn_stopped(strategy, params):
nonlocal should_start
should_start = True
@@ -409,13 +408,13 @@ class TestTranscriptionBotTurnStartStrategy(unittest.IsolatedAsyncioTestCase):
self.assertTrue(should_start)
async def test_it(self):
strategy = TranscriptionBotTurnStartStrategy(timeout=AGGREGATION_TIMEOUT)
strategy = TranscriptionUserTurnStopStrategy(timeout=AGGREGATION_TIMEOUT)
await strategy.setup(self.task_manager)
should_start = None
@strategy.event_handler("on_bot_turn_started")
async def on_bot_turn_started(strategy, params):
@strategy.event_handler("on_user_turn_stopped")
async def on_user_turn_stopped(strategy, params):
nonlocal should_start
should_start = True
@@ -434,13 +433,13 @@ class TestTranscriptionBotTurnStartStrategy(unittest.IsolatedAsyncioTestCase):
self.assertTrue(should_start)
async def test_sie_delay_it(self):
strategy = TranscriptionBotTurnStartStrategy(timeout=AGGREGATION_TIMEOUT)
strategy = TranscriptionUserTurnStopStrategy(timeout=AGGREGATION_TIMEOUT)
await strategy.setup(self.task_manager)
should_start = None
@strategy.event_handler("on_bot_turn_started")
async def on_bot_turn_started(strategy, params):
@strategy.event_handler("on_user_turn_stopped")
async def on_user_turn_stopped(strategy, params):
nonlocal should_start
should_start = True
@@ -477,14 +476,14 @@ class TestTranscriptionBotTurnStartStrategy(unittest.IsolatedAsyncioTestCase):
self.assertTrue(should_start)
class TestExternalBotTurnStartStrategy(unittest.IsolatedAsyncioTestCase):
class TestExternalUserTurnStopStrategy(unittest.IsolatedAsyncioTestCase):
async def test_external_strategy(self):
strategy = ExternalBotTurnStartStrategy()
strategy = ExternalUserTurnStopStrategy()
should_start = None
@strategy.event_handler("on_bot_turn_started")
async def on_bot_turn_started(strategy, params):
@strategy.event_handler("on_user_turn_stopped")
async def on_user_turn_stopped(strategy, params):
nonlocal should_start
should_start = True

View File

@@ -30,11 +30,11 @@ from pipecat.processors.aggregators.llm_response_universal import (
LLMUserAggregatorParams,
)
from pipecat.tests.utils import SleepFrame, run_test
from pipecat.turns.bot import TranscriptionBotTurnStartStrategy
from pipecat.turns.mute import FirstSpeechUserMuteStrategy, FunctionCallUserMuteStrategy
from pipecat.turns.turn_start_strategies import TurnStartStrategies
from pipecat.turns.user_stop import TranscriptionUserTurnStopStrategy
from pipecat.turns.user_turn_strategies import UserTurnStrategies
USER_TURN_END_TIMEOUT = 0.2
USER_TURN_STOP_TIMEOUT = 0.2
TRANSCRIPTION_TIMEOUT = 0.1
@@ -163,18 +163,18 @@ class TestUserAggregator(unittest.IsolatedAsyncioTestCase):
expected_down_frames=expected_down_frames,
)
async def test_user_turn_end_timeout_no_transcription(self):
async def test_user_turn_stop_timeout_no_transcription(self):
context = LLMContext()
user_aggregator = LLMUserAggregator(
context,
params=LLMUserAggregatorParams(user_turn_end_timeout=USER_TURN_END_TIMEOUT),
params=LLMUserAggregatorParams(user_turn_stop_timeout=USER_TURN_STOP_TIMEOUT),
)
timeout = False
@user_aggregator.event_handler("on_user_turn_end_timeout")
async def on_user_turn_end_timeout(aggregator):
@user_aggregator.event_handler("on_user_turn_stop_timeout")
async def on_user_turn_stop_timeout(aggregator):
nonlocal timeout
timeout = True
@@ -183,7 +183,7 @@ class TestUserAggregator(unittest.IsolatedAsyncioTestCase):
frames_to_send = [
VADUserStartedSpeakingFrame(),
VADUserStoppedSpeakingFrame(),
SleepFrame(sleep=USER_TURN_END_TIMEOUT + 0.1),
SleepFrame(sleep=USER_TURN_STOP_TIMEOUT + 0.1),
]
await run_test(
pipeline,
@@ -192,29 +192,29 @@ class TestUserAggregator(unittest.IsolatedAsyncioTestCase):
self.assertTrue(timeout)
async def test_user_turn_end_timeout_transcription(self):
async def test_user_turn_stop_timeout_transcription(self):
context = LLMContext()
user_aggregator = LLMUserAggregator(
context,
params=LLMUserAggregatorParams(
turn_start_strategies=TurnStartStrategies(
bot=[TranscriptionBotTurnStartStrategy(timeout=TRANSCRIPTION_TIMEOUT)],
user_turn_strategies=UserTurnStrategies(
stop=[TranscriptionUserTurnStopStrategy(timeout=TRANSCRIPTION_TIMEOUT)],
),
user_turn_end_timeout=USER_TURN_END_TIMEOUT,
user_turn_stop_timeout=USER_TURN_STOP_TIMEOUT,
),
)
timeout = False
bot_turn = False
@user_aggregator.event_handler("on_bot_turn_started")
async def on_bot_turn_started(aggregator, strategy):
@user_aggregator.event_handler("on_user_turn_stopped")
async def on_user_turn_stopped(aggregator, strategy):
nonlocal bot_turn
bot_turn = True
@user_aggregator.event_handler("on_user_turn_end_timeout")
async def on_user_turn_end_timeout(aggregator):
@user_aggregator.event_handler("on_user_turn_stop_timeout")
async def on_user_turn_stop_timeout(aggregator):
nonlocal timeout
timeout = True
@@ -223,9 +223,9 @@ class TestUserAggregator(unittest.IsolatedAsyncioTestCase):
frames_to_send = [
VADUserStartedSpeakingFrame(),
VADUserStoppedSpeakingFrame(),
SleepFrame(sleep=USER_TURN_END_TIMEOUT - 0.1),
SleepFrame(sleep=USER_TURN_STOP_TIMEOUT - 0.1),
TranscriptionFrame(text="Hello!", user_id="", timestamp="now"),
SleepFrame(sleep=USER_TURN_END_TIMEOUT - 0.1),
SleepFrame(sleep=USER_TURN_STOP_TIMEOUT - 0.1),
SleepFrame(sleep=TRANSCRIPTION_TIMEOUT),
]
await run_test(

View File

@@ -14,7 +14,7 @@ from pipecat.frames.frames import (
VADUserStartedSpeakingFrame,
VADUserStoppedSpeakingFrame,
)
from pipecat.turns.user import (
from pipecat.turns.user_start import (
ExternalUserTurnStartStrategy,
MinWordsUserTurnStartStrategy,
TranscriptionUserTurnStartStrategy,