Add turn-completion fields to LLMSettings and handle them in the typed-service-settings path.

`filter_incomplete_user_turns` and `user_turn_completion_config` were only handled in the legacy dict-based `_update_settings` code path. This adds them to `LLMSettings` and introduces `LLMService._update_settings_from_typed` so the typed path handles them too.
This commit is contained in:
Paul Kompfner
2026-02-13 10:31:25 -05:00
parent 8a4ab611be
commit 444cbb6499
2 changed files with 39 additions and 2 deletions

View File

@@ -59,7 +59,7 @@ from pipecat.processors.aggregators.llm_response import (
from pipecat.processors.aggregators.openai_llm_context import OpenAILLMContext from pipecat.processors.aggregators.openai_llm_context import OpenAILLMContext
from pipecat.processors.frame_processor import FrameDirection from pipecat.processors.frame_processor import FrameDirection
from pipecat.services.ai_service import AIService from pipecat.services.ai_service import AIService
from pipecat.services.settings import ServiceSettings from pipecat.services.settings import LLMSettings, ServiceSettings, is_given
from pipecat.turns.user_turn_completion_mixin import UserTurnCompletionLLMServiceMixin from pipecat.turns.user_turn_completion_mixin import UserTurnCompletionLLMServiceMixin
from pipecat.utils.context.llm_context_summarization import ( from pipecat.utils.context.llm_context_summarization import (
LLMContextSummarizationUtil, LLMContextSummarizationUtil,
@@ -311,6 +311,29 @@ class LLMService(UserTurnCompletionLLMServiceMixin, AIService):
await self._cancel_sequential_runner_task() await self._cancel_sequential_runner_task()
await self._cancel_summary_task() await self._cancel_summary_task()
async def _update_settings_from_typed(self, update: LLMSettings) -> set[str]:
"""Apply a typed settings update, handling turn-completion fields.
Args:
update: A typed LLM settings delta.
Returns:
Set of field names whose values actually changed.
"""
changed = await super()._update_settings_from_typed(update)
if "filter_incomplete_user_turns" in changed:
self._filter_incomplete_user_turns = self._settings.filter_incomplete_user_turns
logger.info(
f"{self}: Incomplete turn filtering "
f"{'enabled' if self._filter_incomplete_user_turns else 'disabled'}"
)
if "user_turn_completion_config" in changed and self._filter_incomplete_user_turns:
self.set_user_turn_completion_config(self._settings.user_turn_completion_config)
return changed
async def _update_settings(self, settings: Mapping[str, Any]): async def _update_settings(self, settings: Mapping[str, Any]):
"""Update LLM service settings. """Update LLM service settings.

View File

@@ -31,10 +31,13 @@ from __future__ import annotations
import copy import copy
from dataclasses import dataclass, field, fields from dataclasses import dataclass, field, fields
from typing import Any, ClassVar, Dict, Mapping, Optional, Set, Type, TypeVar from typing import TYPE_CHECKING, Any, ClassVar, Dict, Mapping, Optional, Set, Type, TypeVar
from loguru import logger from loguru import logger
if TYPE_CHECKING:
from pipecat.turns.user_turn_completion_mixin import UserTurnCompletionConfig
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# NOT_GIVEN sentinel # NOT_GIVEN sentinel
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@@ -258,6 +261,13 @@ class LLMSettings(ServiceSettings):
frequency_penalty: Frequency penalty. frequency_penalty: Frequency penalty.
presence_penalty: Presence penalty. presence_penalty: Presence penalty.
seed: Random seed for reproducibility. seed: Random seed for reproducibility.
filter_incomplete_user_turns: Enable LLM-based turn completion detection
to suppress bot responses when the user was cut off mid-thought.
See ``examples/foundational/22-filter-incomplete-turns.py`` and
``UserTurnCompletionLLMServiceMixin``.
user_turn_completion_config: Configuration for turn completion behavior
when ``filter_incomplete_user_turns`` is enabled. Controls timeouts
and prompts for incomplete turns.
""" """
temperature: Any = field(default_factory=lambda: NOT_GIVEN) temperature: Any = field(default_factory=lambda: NOT_GIVEN)
@@ -267,6 +277,10 @@ class LLMSettings(ServiceSettings):
frequency_penalty: Any = field(default_factory=lambda: NOT_GIVEN) frequency_penalty: Any = field(default_factory=lambda: NOT_GIVEN)
presence_penalty: Any = field(default_factory=lambda: NOT_GIVEN) presence_penalty: Any = field(default_factory=lambda: NOT_GIVEN)
seed: Any = field(default_factory=lambda: NOT_GIVEN) seed: Any = field(default_factory=lambda: NOT_GIVEN)
filter_incomplete_user_turns: bool | _NotGiven = field(default_factory=lambda: NOT_GIVEN)
user_turn_completion_config: UserTurnCompletionConfig | _NotGiven = field(
default_factory=lambda: NOT_GIVEN
)
@dataclass @dataclass