Re-inject turn completion instructions after LLM context reset
When filter_incomplete_user_turns is enabled and an LLMMessagesUpdateFrame replaces the context via set_messages(), the turn completion instructions system message was lost. This caused the LLM to stop emitting turn completion markers. Re-inject the instructions after set_messages() to fix this.
This commit is contained in:
1
changelog/3888.fixed.md
Normal file
1
changelog/3888.fixed.md
Normal file
@@ -0,0 +1 @@
|
||||
- Fixed turn completion instructions being lost when `LLMMessagesUpdateFrame` replaces the LLM context. When `filter_incomplete_user_turns` is enabled, the turn completion system message is now re-injected after context replacement.
|
||||
@@ -642,6 +642,9 @@ class LLMUserAggregator(LLMContextAggregator):
|
||||
|
||||
async def _handle_llm_messages_update(self, frame: LLMMessagesUpdateFrame):
|
||||
self.set_messages(frame.messages)
|
||||
if self._params.filter_incomplete_user_turns:
|
||||
config = self._params.user_turn_completion_config or UserTurnCompletionConfig()
|
||||
self._context.add_message({"role": "system", "content": config.completion_instructions})
|
||||
if frame.run_llm:
|
||||
await self.push_context_frame()
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@ from pipecat.turns.user_mute import (
|
||||
MuteUntilFirstBotCompleteUserMuteStrategy,
|
||||
)
|
||||
from pipecat.turns.user_stop import SpeechTimeoutUserTurnStopStrategy
|
||||
from pipecat.turns.user_turn_completion_mixin import UserTurnCompletionConfig
|
||||
from pipecat.turns.user_turn_strategies import UserTurnStrategies
|
||||
|
||||
USER_TURN_STOP_TIMEOUT = 0.2
|
||||
@@ -155,6 +156,28 @@ class TestLLMUserAggregator(unittest.IsolatedAsyncioTestCase):
|
||||
)
|
||||
assert context.messages[0]["content"] == "Hi there!"
|
||||
|
||||
async def test_llm_messages_update_reinjects_turn_completion_instructions(self):
|
||||
context = LLMContext()
|
||||
params = LLMUserAggregatorParams(filter_incomplete_user_turns=True)
|
||||
pipeline = Pipeline([LLMUserAggregator(context, params=params)])
|
||||
|
||||
new_messages = [
|
||||
{"role": "system", "content": "You are a helpful assistant."},
|
||||
{"role": "user", "content": "Hello!"},
|
||||
]
|
||||
frames_to_send = [LLMMessagesUpdateFrame(messages=new_messages)]
|
||||
await run_test(
|
||||
pipeline,
|
||||
frames_to_send=frames_to_send,
|
||||
)
|
||||
config = UserTurnCompletionConfig()
|
||||
# The context should contain the new messages plus the re-injected instructions
|
||||
assert len(context.messages) == 3
|
||||
assert context.messages[0]["content"] == "You are a helpful assistant."
|
||||
assert context.messages[1]["content"] == "Hello!"
|
||||
assert context.messages[2]["role"] == "system"
|
||||
assert context.messages[2]["content"] == config.completion_instructions
|
||||
|
||||
async def test_default_user_turn_strategies(self):
|
||||
context = LLMContext()
|
||||
user_aggregator = LLMUserAggregator(
|
||||
|
||||
Reference in New Issue
Block a user