Enhance conversation history and runtime variable management
- Update ConversationRecorder to include source and nodeId metadata in transcripts for better context tracking. - Introduce optional variable handling in DynamicVariableStore, allowing for unset variables to be rendered as empty without raising errors. - Refactor WorkflowBrain to apply turn configurations and manage interaction policies dynamically, improving agent responsiveness. - Implement tests to ensure proper handling of updated session variables and workflow metadata in various scenarios.
This commit is contained in:
@@ -7,6 +7,11 @@ from typing import Any
|
||||
from pipecat.audio.turn.smart_turn.local_smart_turn_v3 import LocalSmartTurnAnalyzerV3
|
||||
from pipecat.audio.vad.silero import SileroVADAnalyzer
|
||||
from pipecat.audio.vad.vad_analyzer import VADParams
|
||||
from pipecat.processors.aggregators.llm_context import LLMContext
|
||||
from pipecat.processors.aggregators.llm_response_universal import (
|
||||
LLMUserAggregator,
|
||||
LLMUserAggregatorParams,
|
||||
)
|
||||
from pipecat.turns.user_start import (
|
||||
TranscriptionUserTurnStartStrategy,
|
||||
VADUserTurnStartStrategy,
|
||||
@@ -39,18 +44,21 @@ def _value(config: dict[str, Any], snake: str, camel: str, default: Any) -> Any:
|
||||
return config.get(snake, config.get(camel, default))
|
||||
|
||||
|
||||
def create_vad_analyzer(turn_config: dict[str, Any]) -> SileroVADAnalyzer:
|
||||
def create_vad_params(turn_config: dict[str, Any]) -> VADParams:
|
||||
"""Translate product settings into Pipecat's runtime VAD parameters."""
|
||||
vad = _section(turn_config, "vad", "vad")
|
||||
return SileroVADAnalyzer(
|
||||
params=VADParams(
|
||||
confidence=float(vad.get("confidence", DEFAULT_VAD["confidence"])),
|
||||
start_secs=float(_value(vad, "start_secs", "startSecs", 0.2)),
|
||||
stop_secs=float(_value(vad, "stop_secs", "stopSecs", 0.2)),
|
||||
min_volume=float(_value(vad, "min_volume", "minVolume", 0.6)),
|
||||
)
|
||||
return VADParams(
|
||||
confidence=float(vad.get("confidence", DEFAULT_VAD["confidence"])),
|
||||
start_secs=float(_value(vad, "start_secs", "startSecs", 0.2)),
|
||||
stop_secs=float(_value(vad, "stop_secs", "stopSecs", 0.2)),
|
||||
min_volume=float(_value(vad, "min_volume", "minVolume", 0.6)),
|
||||
)
|
||||
|
||||
|
||||
def create_vad_analyzer(turn_config: dict[str, Any]) -> SileroVADAnalyzer:
|
||||
return SileroVADAnalyzer(params=create_vad_params(turn_config))
|
||||
|
||||
|
||||
def create_user_turn_strategies(
|
||||
turn_config: dict[str, Any], *, enable_interruptions: bool
|
||||
) -> UserTurnStrategies:
|
||||
@@ -87,3 +95,34 @@ def create_user_turn_strategies(
|
||||
)
|
||||
]
|
||||
return UserTurnStrategies(start=start, stop=stop)
|
||||
|
||||
|
||||
class ConfigurableLLMUserAggregator(LLMUserAggregator):
|
||||
"""LLM user aggregator with one stable project-level runtime update API.
|
||||
|
||||
Pipecat 1.5 exposes ``UserTurnController.update_strategies`` but does not
|
||||
surface it on ``LLMUserAggregator``. Keeping that version-specific bridge
|
||||
here prevents Workflow orchestration from depending on Pipecat internals.
|
||||
VAD threshold updates still use Pipecat's public ``VADParamsUpdateFrame``.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
context: LLMContext,
|
||||
*,
|
||||
params: LLMUserAggregatorParams | None = None,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
super().__init__(context, params=params, **kwargs)
|
||||
|
||||
async def apply_turn_strategies(
|
||||
self,
|
||||
turn_config: dict[str, Any],
|
||||
*,
|
||||
enable_interruptions: bool,
|
||||
) -> None:
|
||||
strategies = create_user_turn_strategies(
|
||||
turn_config,
|
||||
enable_interruptions=enable_interruptions,
|
||||
)
|
||||
await self._user_turn_controller.update_strategies(strategies)
|
||||
|
||||
Reference in New Issue
Block a user