Add ServiceSwitcherStrategyFailover for automatic failover on service errors (#3870)
* Add ServiceSwitcherStrategyFailover for automatic error-based service switching Introduce a strategy hierarchy: ServiceSwitcherStrategy (base) → ServiceSwitcherStrategyManual (handles ManuallySwitchServiceFrame) → ServiceSwitcherStrategyFailover (adds error-based failover). ServiceSwitcher now defaults to ServiceSwitcherStrategyManual with strategy_type optional. Non-fatal ErrorFrames are forwarded to the strategy via handle_error(). * Move metadata request into _set_active_if_available Requesting metadata is part of making a service active, so it belongs alongside setting _active_service and firing on_service_switched. This removes the duplicate queue_frame calls from ServiceSwitcher push_frame and process_frame.
This commit is contained in:
@@ -17,7 +17,7 @@ from pipecat.frames.frames import LLMRunFrame, ManuallySwitchServiceFrame
|
||||
from pipecat.pipeline.llm_switcher import LLMSwitcher
|
||||
from pipecat.pipeline.pipeline import Pipeline
|
||||
from pipecat.pipeline.runner import PipelineRunner
|
||||
from pipecat.pipeline.service_switcher import ServiceSwitcher, ServiceSwitcherStrategyManual
|
||||
from pipecat.pipeline.service_switcher import ServiceSwitcher
|
||||
from pipecat.pipeline.task import PipelineParams, PipelineTask
|
||||
from pipecat.processors.aggregators.llm_context import LLMContext
|
||||
from pipecat.processors.aggregators.llm_response_universal import (
|
||||
@@ -96,9 +96,8 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
|
||||
|
||||
stt_cartesia = CartesiaSTTService(api_key=os.getenv("CARTESIA_API_KEY"))
|
||||
stt_deepgram = DeepgramSTTService(api_key=os.getenv("DEEPGRAM_API_KEY"))
|
||||
stt_switcher = ServiceSwitcher(
|
||||
services=[stt_cartesia, stt_deepgram], strategy_type=ServiceSwitcherStrategyManual
|
||||
)
|
||||
# Uses ServiceSwitcherStrategyManual by default
|
||||
stt_switcher = ServiceSwitcher(services=[stt_cartesia, stt_deepgram])
|
||||
|
||||
tts_cartesia = CartesiaTTSService(
|
||||
api_key=os.getenv("CARTESIA_API_KEY"),
|
||||
@@ -112,9 +111,8 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
|
||||
voice="aura-2-helena-en",
|
||||
),
|
||||
)
|
||||
tts_switcher = ServiceSwitcher(
|
||||
services=[tts_cartesia, tts_deepgram], strategy_type=ServiceSwitcherStrategyManual
|
||||
)
|
||||
# Uses ServiceSwitcherStrategyManual by default
|
||||
tts_switcher = ServiceSwitcher(services=[tts_cartesia, tts_deepgram])
|
||||
|
||||
system_prompt = "You are a helpful LLM in a WebRTC call. Your goal is to demonstrate your capabilities in a succinct way. Your output will be spoken aloud, so avoid special characters that can't easily be spoken, such as emojis or bullet points. Respond to what the user said in a creative and helpful way."
|
||||
|
||||
@@ -126,9 +124,8 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
|
||||
api_key=os.getenv("GOOGLE_API_KEY"),
|
||||
settings=GoogleLLMService.Settings(system_instruction=system_prompt),
|
||||
)
|
||||
llm_switcher = LLMSwitcher(
|
||||
llms=[llm_openai, llm_google], strategy_type=ServiceSwitcherStrategyManual
|
||||
)
|
||||
# Uses ServiceSwitcherStrategyManual by default
|
||||
llm_switcher = LLMSwitcher(llms=[llm_openai, llm_google])
|
||||
# Register a "classic" function
|
||||
llm_switcher.register_function("get_current_weather", fetch_weather_from_api)
|
||||
# Register a "direct" function
|
||||
|
||||
Reference in New Issue
Block a user