Add Settings subclasses to all services and auto-discovered init tests
- Add dedicated Settings subclasses to 20 LLM services that were borrowing parent Settings classes (e.g. AzureLLMSettings, GroqLLMSettings) so users don't need cross-module imports - Fix field defaults to NOT_GIVEN in BaseWhisperSTTSettings, OpenAIRealtimeSTTSettings, and NvidiaSegmentedSTTSettings for delta-mode safety - Fix incomplete default_settings in AWS, Cartesia, ElevenLabs, Fish, and Whisper services so validate_complete() passes - Add auto-discovered tests that verify all Settings classes default to NOT_GIVEN (delta safety) and all services initialize with complete settings (store completeness)
This commit is contained in:
@@ -98,6 +98,7 @@ class AWSTranscribeSTTService(WebsocketSTTService):
|
|||||||
"""
|
"""
|
||||||
# 1. Initialize default_settings with hardcoded defaults
|
# 1. Initialize default_settings with hardcoded defaults
|
||||||
default_settings = AWSTranscribeSTTSettings(
|
default_settings = AWSTranscribeSTTSettings(
|
||||||
|
model=None,
|
||||||
language=self.language_to_service_language(Language.EN) or "en-US",
|
language=self.language_to_service_language(Language.EN) or "en-US",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
"""Azure OpenAI service implementation for the Pipecat AI framework."""
|
"""Azure OpenAI service implementation for the Pipecat AI framework."""
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
@@ -16,6 +17,13 @@ from pipecat.services.openai.llm import OpenAILLMService
|
|||||||
from pipecat.services.settings import _warn_deprecated_param
|
from pipecat.services.settings import _warn_deprecated_param
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class AzureLLMSettings(OpenAILLMSettings):
|
||||||
|
"""Settings for Azure OpenAI LLM service."""
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class AzureLLMService(OpenAILLMService):
|
class AzureLLMService(OpenAILLMService):
|
||||||
"""A service for interacting with Azure OpenAI using the OpenAI-compatible interface.
|
"""A service for interacting with Azure OpenAI using the OpenAI-compatible interface.
|
||||||
|
|
||||||
@@ -30,7 +38,7 @@ class AzureLLMService(OpenAILLMService):
|
|||||||
endpoint: str,
|
endpoint: str,
|
||||||
model: Optional[str] = None,
|
model: Optional[str] = None,
|
||||||
api_version: str = "2024-09-01-preview",
|
api_version: str = "2024-09-01-preview",
|
||||||
settings: Optional[OpenAILLMSettings] = None,
|
settings: Optional[AzureLLMSettings] = None,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
):
|
):
|
||||||
"""Initialize the Azure LLM service.
|
"""Initialize the Azure LLM service.
|
||||||
@@ -49,11 +57,11 @@ class AzureLLMService(OpenAILLMService):
|
|||||||
**kwargs: Additional keyword arguments passed to OpenAILLMService.
|
**kwargs: Additional keyword arguments passed to OpenAILLMService.
|
||||||
"""
|
"""
|
||||||
# 1. Initialize default_settings with hardcoded defaults
|
# 1. Initialize default_settings with hardcoded defaults
|
||||||
default_settings = OpenAILLMSettings(model="gpt-4o")
|
default_settings = AzureLLMSettings(model="gpt-4o")
|
||||||
|
|
||||||
# 2. Apply direct init arg overrides (deprecated)
|
# 2. Apply direct init arg overrides (deprecated)
|
||||||
if model is not None:
|
if model is not None:
|
||||||
_warn_deprecated_param("model", OpenAILLMSettings, "model")
|
_warn_deprecated_param("model", AzureLLMSettings, "model")
|
||||||
default_settings.model = model
|
default_settings.model = model
|
||||||
|
|
||||||
# 4. Apply settings delta (canonical API, always wins)
|
# 4. Apply settings delta (canonical API, always wins)
|
||||||
|
|||||||
@@ -6,9 +6,11 @@
|
|||||||
|
|
||||||
"""Azure OpenAI Realtime LLM service implementation."""
|
"""Azure OpenAI Realtime LLM service implementation."""
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
|
||||||
from pipecat.services.openai.realtime.llm import OpenAIRealtimeLLMService
|
from pipecat.services.openai.realtime.llm import OpenAIRealtimeLLMService, OpenAIRealtimeLLMSettings
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from websockets.asyncio.client import connect as websocket_connect
|
from websockets.asyncio.client import connect as websocket_connect
|
||||||
@@ -18,6 +20,13 @@ except ModuleNotFoundError as e:
|
|||||||
raise Exception(f"Missing module: {e}")
|
raise Exception(f"Missing module: {e}")
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class AzureRealtimeLLMSettings(OpenAIRealtimeLLMSettings):
|
||||||
|
"""Settings for Azure Realtime LLM service."""
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class AzureRealtimeLLMService(OpenAIRealtimeLLMService):
|
class AzureRealtimeLLMService(OpenAIRealtimeLLMService):
|
||||||
"""Azure OpenAI Realtime LLM service with Azure-specific authentication.
|
"""Azure OpenAI Realtime LLM service with Azure-specific authentication.
|
||||||
|
|
||||||
|
|||||||
@@ -301,6 +301,7 @@ class CartesiaTTSService(AudioContextTTSService):
|
|||||||
# 1. Initialize default_settings with hardcoded defaults
|
# 1. Initialize default_settings with hardcoded defaults
|
||||||
default_settings = CartesiaTTSSettings(
|
default_settings = CartesiaTTSSettings(
|
||||||
model="sonic-3",
|
model="sonic-3",
|
||||||
|
voice=None,
|
||||||
language=language_to_cartesia_language(Language.EN),
|
language=language_to_cartesia_language(Language.EN),
|
||||||
generation_config=None,
|
generation_config=None,
|
||||||
pronunciation_dict_id=None,
|
pronunciation_dict_id=None,
|
||||||
@@ -745,6 +746,7 @@ class CartesiaHttpTTSService(TTSService):
|
|||||||
# 1. Initialize default_settings with hardcoded defaults
|
# 1. Initialize default_settings with hardcoded defaults
|
||||||
default_settings = CartesiaTTSSettings(
|
default_settings = CartesiaTTSSettings(
|
||||||
model="sonic-3",
|
model="sonic-3",
|
||||||
|
voice=None,
|
||||||
language=language_to_cartesia_language(Language.EN),
|
language=language_to_cartesia_language(Language.EN),
|
||||||
generation_config=None,
|
generation_config=None,
|
||||||
pronunciation_dict_id=None,
|
pronunciation_dict_id=None,
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
"""Cerebras LLM service implementation using OpenAI-compatible interface."""
|
"""Cerebras LLM service implementation using OpenAI-compatible interface."""
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
@@ -16,6 +17,13 @@ from pipecat.services.openai.llm import OpenAILLMService
|
|||||||
from pipecat.services.settings import _warn_deprecated_param
|
from pipecat.services.settings import _warn_deprecated_param
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class CerebrasLLMSettings(OpenAILLMSettings):
|
||||||
|
"""Settings for Cerebras LLM service."""
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class CerebrasLLMService(OpenAILLMService):
|
class CerebrasLLMService(OpenAILLMService):
|
||||||
"""A service for interacting with Cerebras's API using the OpenAI-compatible interface.
|
"""A service for interacting with Cerebras's API using the OpenAI-compatible interface.
|
||||||
|
|
||||||
@@ -29,7 +37,7 @@ class CerebrasLLMService(OpenAILLMService):
|
|||||||
api_key: str,
|
api_key: str,
|
||||||
base_url: str = "https://api.cerebras.ai/v1",
|
base_url: str = "https://api.cerebras.ai/v1",
|
||||||
model: Optional[str] = None,
|
model: Optional[str] = None,
|
||||||
settings: Optional[OpenAILLMSettings] = None,
|
settings: Optional[CerebrasLLMSettings] = None,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
):
|
):
|
||||||
"""Initialize the Cerebras LLM service.
|
"""Initialize the Cerebras LLM service.
|
||||||
@@ -47,11 +55,11 @@ class CerebrasLLMService(OpenAILLMService):
|
|||||||
**kwargs: Additional keyword arguments passed to OpenAILLMService.
|
**kwargs: Additional keyword arguments passed to OpenAILLMService.
|
||||||
"""
|
"""
|
||||||
# 1. Initialize default_settings with hardcoded defaults
|
# 1. Initialize default_settings with hardcoded defaults
|
||||||
default_settings = OpenAILLMSettings(model="gpt-oss-120b")
|
default_settings = CerebrasLLMSettings(model="gpt-oss-120b")
|
||||||
|
|
||||||
# 2. Apply direct init arg overrides (deprecated)
|
# 2. Apply direct init arg overrides (deprecated)
|
||||||
if model is not None:
|
if model is not None:
|
||||||
_warn_deprecated_param("model", OpenAILLMSettings, "model")
|
_warn_deprecated_param("model", CerebrasLLMSettings, "model")
|
||||||
default_settings.model = model
|
default_settings.model = model
|
||||||
|
|
||||||
# 4. Apply settings delta (canonical API, always wins)
|
# 4. Apply settings delta (canonical API, always wins)
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
"""DeepSeek LLM service implementation using OpenAI-compatible interface."""
|
"""DeepSeek LLM service implementation using OpenAI-compatible interface."""
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
@@ -16,6 +17,13 @@ from pipecat.services.openai.llm import OpenAILLMService
|
|||||||
from pipecat.services.settings import _warn_deprecated_param
|
from pipecat.services.settings import _warn_deprecated_param
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class DeepSeekLLMSettings(OpenAILLMSettings):
|
||||||
|
"""Settings for DeepSeek LLM service."""
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class DeepSeekLLMService(OpenAILLMService):
|
class DeepSeekLLMService(OpenAILLMService):
|
||||||
"""A service for interacting with DeepSeek's API using the OpenAI-compatible interface.
|
"""A service for interacting with DeepSeek's API using the OpenAI-compatible interface.
|
||||||
|
|
||||||
@@ -29,7 +37,7 @@ class DeepSeekLLMService(OpenAILLMService):
|
|||||||
api_key: str,
|
api_key: str,
|
||||||
base_url: str = "https://api.deepseek.com/v1",
|
base_url: str = "https://api.deepseek.com/v1",
|
||||||
model: Optional[str] = None,
|
model: Optional[str] = None,
|
||||||
settings: Optional[OpenAILLMSettings] = None,
|
settings: Optional[DeepSeekLLMSettings] = None,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
):
|
):
|
||||||
"""Initialize the DeepSeek LLM service.
|
"""Initialize the DeepSeek LLM service.
|
||||||
@@ -47,11 +55,11 @@ class DeepSeekLLMService(OpenAILLMService):
|
|||||||
**kwargs: Additional keyword arguments passed to OpenAILLMService.
|
**kwargs: Additional keyword arguments passed to OpenAILLMService.
|
||||||
"""
|
"""
|
||||||
# 1. Initialize default_settings with hardcoded defaults
|
# 1. Initialize default_settings with hardcoded defaults
|
||||||
default_settings = OpenAILLMSettings(model="deepseek-chat")
|
default_settings = DeepSeekLLMSettings(model="deepseek-chat")
|
||||||
|
|
||||||
# 2. Apply direct init arg overrides (deprecated)
|
# 2. Apply direct init arg overrides (deprecated)
|
||||||
if model is not None:
|
if model is not None:
|
||||||
_warn_deprecated_param("model", OpenAILLMSettings, "model")
|
_warn_deprecated_param("model", DeepSeekLLMSettings, "model")
|
||||||
default_settings.model = model
|
default_settings.model = model
|
||||||
|
|
||||||
# 4. Apply settings delta (canonical API, always wins)
|
# 4. Apply settings delta (canonical API, always wins)
|
||||||
|
|||||||
@@ -418,6 +418,14 @@ class ElevenLabsTTSService(AudioContextTTSService):
|
|||||||
# 1. Initialize default_settings with hardcoded defaults
|
# 1. Initialize default_settings with hardcoded defaults
|
||||||
default_settings = ElevenLabsTTSSettings(
|
default_settings = ElevenLabsTTSSettings(
|
||||||
model="eleven_turbo_v2_5",
|
model="eleven_turbo_v2_5",
|
||||||
|
voice=None,
|
||||||
|
language=None,
|
||||||
|
stability=None,
|
||||||
|
similarity_boost=None,
|
||||||
|
style=None,
|
||||||
|
use_speaker_boost=None,
|
||||||
|
speed=None,
|
||||||
|
apply_text_normalization=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Track init-only URL params through the override chain
|
# Track init-only URL params through the override chain
|
||||||
@@ -986,6 +994,15 @@ class ElevenLabsHttpTTSService(TTSService):
|
|||||||
# 1. Initialize default_settings with hardcoded defaults
|
# 1. Initialize default_settings with hardcoded defaults
|
||||||
default_settings = ElevenLabsHttpTTSSettings(
|
default_settings = ElevenLabsHttpTTSSettings(
|
||||||
model="eleven_turbo_v2_5",
|
model="eleven_turbo_v2_5",
|
||||||
|
voice=None,
|
||||||
|
language=None,
|
||||||
|
optimize_streaming_latency=None,
|
||||||
|
stability=None,
|
||||||
|
similarity_boost=None,
|
||||||
|
style=None,
|
||||||
|
use_speaker_boost=None,
|
||||||
|
speed=None,
|
||||||
|
apply_text_normalization=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
# 2. Apply direct init arg overrides (deprecated)
|
# 2. Apply direct init arg overrides (deprecated)
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
"""Fireworks AI service implementation using OpenAI-compatible interface."""
|
"""Fireworks AI service implementation using OpenAI-compatible interface."""
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
@@ -16,6 +17,13 @@ from pipecat.services.openai.llm import OpenAILLMService
|
|||||||
from pipecat.services.settings import _warn_deprecated_param
|
from pipecat.services.settings import _warn_deprecated_param
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class FireworksLLMSettings(OpenAILLMSettings):
|
||||||
|
"""Settings for Fireworks LLM service."""
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class FireworksLLMService(OpenAILLMService):
|
class FireworksLLMService(OpenAILLMService):
|
||||||
"""A service for interacting with Fireworks AI using the OpenAI-compatible interface.
|
"""A service for interacting with Fireworks AI using the OpenAI-compatible interface.
|
||||||
|
|
||||||
@@ -29,7 +37,7 @@ class FireworksLLMService(OpenAILLMService):
|
|||||||
api_key: str,
|
api_key: str,
|
||||||
model: Optional[str] = None,
|
model: Optional[str] = None,
|
||||||
base_url: str = "https://api.fireworks.ai/inference/v1",
|
base_url: str = "https://api.fireworks.ai/inference/v1",
|
||||||
settings: Optional[OpenAILLMSettings] = None,
|
settings: Optional[FireworksLLMSettings] = None,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
):
|
):
|
||||||
"""Initialize the Fireworks LLM service.
|
"""Initialize the Fireworks LLM service.
|
||||||
@@ -47,11 +55,11 @@ class FireworksLLMService(OpenAILLMService):
|
|||||||
**kwargs: Additional keyword arguments passed to OpenAILLMService.
|
**kwargs: Additional keyword arguments passed to OpenAILLMService.
|
||||||
"""
|
"""
|
||||||
# 1. Initialize default_settings with hardcoded defaults
|
# 1. Initialize default_settings with hardcoded defaults
|
||||||
default_settings = OpenAILLMSettings(model="accounts/fireworks/models/firefunction-v2")
|
default_settings = FireworksLLMSettings(model="accounts/fireworks/models/firefunction-v2")
|
||||||
|
|
||||||
# 2. Apply direct init arg overrides (deprecated)
|
# 2. Apply direct init arg overrides (deprecated)
|
||||||
if model is not None:
|
if model is not None:
|
||||||
_warn_deprecated_param("model", OpenAILLMSettings, "model")
|
_warn_deprecated_param("model", FireworksLLMSettings, "model")
|
||||||
default_settings.model = model
|
default_settings.model = model
|
||||||
|
|
||||||
# 4. Apply settings delta (canonical API, always wins)
|
# 4. Apply settings delta (canonical API, always wins)
|
||||||
|
|||||||
@@ -173,6 +173,7 @@ class FishAudioTTSService(InterruptibleTTSService):
|
|||||||
default_settings = FishAudioTTSSettings(
|
default_settings = FishAudioTTSSettings(
|
||||||
model="s1",
|
model="s1",
|
||||||
voice=None,
|
voice=None,
|
||||||
|
language=None,
|
||||||
latency="normal",
|
latency="normal",
|
||||||
normalize=True,
|
normalize=True,
|
||||||
prosody_speed=1.0,
|
prosody_speed=1.0,
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ streaming responses, and tool usage.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
from dataclasses import dataclass
|
||||||
from typing import List, Optional, Union
|
from typing import List, Optional, Union
|
||||||
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
@@ -41,6 +42,13 @@ except ModuleNotFoundError as e:
|
|||||||
raise Exception(f"Missing module: {e}")
|
raise Exception(f"Missing module: {e}")
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class GeminiLiveVertexLLMSettings(GeminiLiveLLMSettings):
|
||||||
|
"""Settings for Gemini Live Vertex LLM service."""
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class GeminiLiveVertexLLMService(GeminiLiveLLMService):
|
class GeminiLiveVertexLLMService(GeminiLiveLLMService):
|
||||||
"""Provides access to Google's Gemini Live model via Vertex AI.
|
"""Provides access to Google's Gemini Live model via Vertex AI.
|
||||||
|
|
||||||
@@ -63,7 +71,7 @@ class GeminiLiveVertexLLMService(GeminiLiveLLMService):
|
|||||||
system_instruction: Optional[str] = None,
|
system_instruction: Optional[str] = None,
|
||||||
tools: Optional[Union[List[dict], ToolsSchema]] = None,
|
tools: Optional[Union[List[dict], ToolsSchema]] = None,
|
||||||
params: Optional[InputParams] = None,
|
params: Optional[InputParams] = None,
|
||||||
settings: Optional[GeminiLiveLLMSettings] = None,
|
settings: Optional[GeminiLiveVertexLLMSettings] = None,
|
||||||
inference_on_context_initialization: bool = True,
|
inference_on_context_initialization: bool = True,
|
||||||
file_api_base_url: str = "https://generativelanguage.googleapis.com/v1beta/files",
|
file_api_base_url: str = "https://generativelanguage.googleapis.com/v1beta/files",
|
||||||
http_options: Optional[HttpOptions] = None,
|
http_options: Optional[HttpOptions] = None,
|
||||||
@@ -122,7 +130,7 @@ class GeminiLiveVertexLLMService(GeminiLiveLLMService):
|
|||||||
# double deprecation warnings from the parent.
|
# double deprecation warnings from the parent.
|
||||||
|
|
||||||
# 1. Initialize default_settings with hardcoded defaults
|
# 1. Initialize default_settings with hardcoded defaults
|
||||||
default_settings = GeminiLiveLLMSettings(
|
default_settings = GeminiLiveVertexLLMSettings(
|
||||||
model="google/gemini-live-2.5-flash-native-audio",
|
model="google/gemini-live-2.5-flash-native-audio",
|
||||||
frequency_penalty=None,
|
frequency_penalty=None,
|
||||||
max_tokens=4096,
|
max_tokens=4096,
|
||||||
@@ -146,12 +154,12 @@ class GeminiLiveVertexLLMService(GeminiLiveLLMService):
|
|||||||
|
|
||||||
# 2. Apply direct init arg overrides (deprecated)
|
# 2. Apply direct init arg overrides (deprecated)
|
||||||
if model is not None:
|
if model is not None:
|
||||||
_warn_deprecated_param("model", GeminiLiveLLMSettings, "model")
|
_warn_deprecated_param("model", GeminiLiveVertexLLMSettings, "model")
|
||||||
default_settings.model = model
|
default_settings.model = model
|
||||||
|
|
||||||
# 3. Apply params overrides — only if settings not provided
|
# 3. Apply params overrides — only if settings not provided
|
||||||
if params is not None:
|
if params is not None:
|
||||||
_warn_deprecated_param("params", GeminiLiveLLMSettings)
|
_warn_deprecated_param("params", GeminiLiveVertexLLMSettings)
|
||||||
if not settings:
|
if not settings:
|
||||||
default_settings.frequency_penalty = params.frequency_penalty
|
default_settings.frequency_penalty = params.frequency_penalty
|
||||||
default_settings.max_tokens = params.max_tokens
|
default_settings.max_tokens = params.max_tokens
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ API format through Google's Gemini API OpenAI compatibility layer.
|
|||||||
|
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
from dataclasses import dataclass
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from openai import AsyncStream
|
from openai import AsyncStream
|
||||||
@@ -32,6 +33,13 @@ from pipecat.services.openai.llm import OpenAILLMService
|
|||||||
from pipecat.services.settings import _warn_deprecated_param
|
from pipecat.services.settings import _warn_deprecated_param
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class GoogleOpenAILLMSettings(OpenAILLMSettings):
|
||||||
|
"""Settings for Google OpenAI-compatible LLM service."""
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class GoogleLLMOpenAIBetaService(OpenAILLMService):
|
class GoogleLLMOpenAIBetaService(OpenAILLMService):
|
||||||
"""Google LLM service using OpenAI-compatible API format.
|
"""Google LLM service using OpenAI-compatible API format.
|
||||||
|
|
||||||
@@ -56,7 +64,7 @@ class GoogleLLMOpenAIBetaService(OpenAILLMService):
|
|||||||
api_key: str,
|
api_key: str,
|
||||||
base_url: str = "https://generativelanguage.googleapis.com/v1beta/openai/",
|
base_url: str = "https://generativelanguage.googleapis.com/v1beta/openai/",
|
||||||
model: Optional[str] = None,
|
model: Optional[str] = None,
|
||||||
settings: Optional[OpenAILLMSettings] = None,
|
settings: Optional[GoogleOpenAILLMSettings] = None,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
):
|
):
|
||||||
"""Initialize the Google LLM service.
|
"""Initialize the Google LLM service.
|
||||||
@@ -85,11 +93,11 @@ class GoogleLLMOpenAIBetaService(OpenAILLMService):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# 1. Initialize default_settings with hardcoded defaults
|
# 1. Initialize default_settings with hardcoded defaults
|
||||||
default_settings = OpenAILLMSettings(model="gemini-2.0-flash")
|
default_settings = GoogleOpenAILLMSettings(model="gemini-2.0-flash")
|
||||||
|
|
||||||
# 2. Apply direct init arg overrides (deprecated)
|
# 2. Apply direct init arg overrides (deprecated)
|
||||||
if model is not None:
|
if model is not None:
|
||||||
_warn_deprecated_param("model", OpenAILLMSettings, "model")
|
_warn_deprecated_param("model", GoogleOpenAILLMSettings, "model")
|
||||||
default_settings.model = model
|
default_settings.model = model
|
||||||
|
|
||||||
# 4. Apply settings delta (canonical API, always wins)
|
# 4. Apply settings delta (canonical API, always wins)
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ extending the GoogleLLMService with Vertex AI authentication.
|
|||||||
|
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
# Suppress gRPC fork warnings
|
# Suppress gRPC fork warnings
|
||||||
os.environ["GRPC_ENABLE_FORK_SUPPORT"] = "false"
|
os.environ["GRPC_ENABLE_FORK_SUPPORT"] = "false"
|
||||||
@@ -39,6 +40,13 @@ except ModuleNotFoundError as e:
|
|||||||
raise Exception(f"Missing module: {e}")
|
raise Exception(f"Missing module: {e}")
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class GoogleVertexLLMSettings(GoogleLLMSettings):
|
||||||
|
"""Settings for Google Vertex LLM service."""
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class GoogleVertexLLMService(GoogleLLMService):
|
class GoogleVertexLLMService(GoogleLLMService):
|
||||||
"""Google Vertex AI LLM service extending GoogleLLMService.
|
"""Google Vertex AI LLM service extending GoogleLLMService.
|
||||||
|
|
||||||
@@ -104,7 +112,7 @@ class GoogleVertexLLMService(GoogleLLMService):
|
|||||||
location: Optional[str] = None,
|
location: Optional[str] = None,
|
||||||
project_id: Optional[str] = None,
|
project_id: Optional[str] = None,
|
||||||
params: Optional[GoogleLLMService.InputParams] = None,
|
params: Optional[GoogleLLMService.InputParams] = None,
|
||||||
settings: Optional[GoogleLLMSettings] = None,
|
settings: Optional[GoogleVertexLLMSettings] = None,
|
||||||
system_instruction: Optional[str] = None,
|
system_instruction: Optional[str] = None,
|
||||||
tools: Optional[list] = None,
|
tools: Optional[list] = None,
|
||||||
tool_config: Optional[dict] = None,
|
tool_config: Optional[dict] = None,
|
||||||
@@ -183,7 +191,7 @@ class GoogleVertexLLMService(GoogleLLMService):
|
|||||||
self._location = location
|
self._location = location
|
||||||
|
|
||||||
# 1. Initialize default_settings with hardcoded defaults
|
# 1. Initialize default_settings with hardcoded defaults
|
||||||
default_settings = GoogleLLMSettings(
|
default_settings = GoogleVertexLLMSettings(
|
||||||
model="gemini-2.5-flash",
|
model="gemini-2.5-flash",
|
||||||
max_tokens=4096,
|
max_tokens=4096,
|
||||||
temperature=None,
|
temperature=None,
|
||||||
@@ -200,12 +208,12 @@ class GoogleVertexLLMService(GoogleLLMService):
|
|||||||
|
|
||||||
# 2. Apply direct init arg overrides (deprecated)
|
# 2. Apply direct init arg overrides (deprecated)
|
||||||
if model is not None:
|
if model is not None:
|
||||||
_warn_deprecated_param("model", GoogleLLMSettings, "model")
|
_warn_deprecated_param("model", GoogleVertexLLMSettings, "model")
|
||||||
default_settings.model = model
|
default_settings.model = model
|
||||||
|
|
||||||
# 3. Apply params overrides — only if settings not provided
|
# 3. Apply params overrides — only if settings not provided
|
||||||
if params is not None:
|
if params is not None:
|
||||||
_warn_deprecated_param("params", GoogleLLMSettings)
|
_warn_deprecated_param("params", GoogleVertexLLMSettings)
|
||||||
if not settings:
|
if not settings:
|
||||||
default_settings.max_tokens = params.max_tokens
|
default_settings.max_tokens = params.max_tokens
|
||||||
default_settings.temperature = params.temperature
|
default_settings.temperature = params.temperature
|
||||||
|
|||||||
@@ -70,6 +70,13 @@ class GrokContextAggregatorPair:
|
|||||||
return self._assistant
|
return self._assistant
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class GrokLLMSettings(OpenAILLMSettings):
|
||||||
|
"""Settings for Grok LLM service."""
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class GrokLLMService(OpenAILLMService):
|
class GrokLLMService(OpenAILLMService):
|
||||||
"""A service for interacting with Grok's API using the OpenAI-compatible interface.
|
"""A service for interacting with Grok's API using the OpenAI-compatible interface.
|
||||||
|
|
||||||
@@ -85,7 +92,7 @@ class GrokLLMService(OpenAILLMService):
|
|||||||
api_key: str,
|
api_key: str,
|
||||||
base_url: str = "https://api.x.ai/v1",
|
base_url: str = "https://api.x.ai/v1",
|
||||||
model: Optional[str] = None,
|
model: Optional[str] = None,
|
||||||
settings: Optional[OpenAILLMSettings] = None,
|
settings: Optional[GrokLLMSettings] = None,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
):
|
):
|
||||||
"""Initialize the GrokLLMService with API key and model.
|
"""Initialize the GrokLLMService with API key and model.
|
||||||
@@ -103,11 +110,11 @@ class GrokLLMService(OpenAILLMService):
|
|||||||
**kwargs: Additional keyword arguments passed to OpenAILLMService.
|
**kwargs: Additional keyword arguments passed to OpenAILLMService.
|
||||||
"""
|
"""
|
||||||
# 1. Initialize default_settings with hardcoded defaults
|
# 1. Initialize default_settings with hardcoded defaults
|
||||||
default_settings = OpenAILLMSettings(model="grok-3-beta")
|
default_settings = GrokLLMSettings(model="grok-3-beta")
|
||||||
|
|
||||||
# 2. Apply direct init arg overrides (deprecated)
|
# 2. Apply direct init arg overrides (deprecated)
|
||||||
if model is not None:
|
if model is not None:
|
||||||
_warn_deprecated_param("model", OpenAILLMSettings, "model")
|
_warn_deprecated_param("model", GrokLLMSettings, "model")
|
||||||
default_settings.model = model
|
default_settings.model = model
|
||||||
|
|
||||||
# 4. Apply settings delta (canonical API, always wins)
|
# 4. Apply settings delta (canonical API, always wins)
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
"""Groq LLM Service implementation using OpenAI-compatible interface."""
|
"""Groq LLM Service implementation using OpenAI-compatible interface."""
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
@@ -15,6 +16,13 @@ from pipecat.services.openai.llm import OpenAILLMService
|
|||||||
from pipecat.services.settings import _warn_deprecated_param
|
from pipecat.services.settings import _warn_deprecated_param
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class GroqLLMSettings(OpenAILLMSettings):
|
||||||
|
"""Settings for Groq LLM service."""
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class GroqLLMService(OpenAILLMService):
|
class GroqLLMService(OpenAILLMService):
|
||||||
"""A service for interacting with Groq's API using the OpenAI-compatible interface.
|
"""A service for interacting with Groq's API using the OpenAI-compatible interface.
|
||||||
|
|
||||||
@@ -28,7 +36,7 @@ class GroqLLMService(OpenAILLMService):
|
|||||||
api_key: str,
|
api_key: str,
|
||||||
base_url: str = "https://api.groq.com/openai/v1",
|
base_url: str = "https://api.groq.com/openai/v1",
|
||||||
model: Optional[str] = None,
|
model: Optional[str] = None,
|
||||||
settings: Optional[OpenAILLMSettings] = None,
|
settings: Optional[GroqLLMSettings] = None,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
):
|
):
|
||||||
"""Initialize Groq LLM service.
|
"""Initialize Groq LLM service.
|
||||||
@@ -46,11 +54,11 @@ class GroqLLMService(OpenAILLMService):
|
|||||||
**kwargs: Additional keyword arguments passed to OpenAILLMService.
|
**kwargs: Additional keyword arguments passed to OpenAILLMService.
|
||||||
"""
|
"""
|
||||||
# 1. Initialize default_settings with hardcoded defaults
|
# 1. Initialize default_settings with hardcoded defaults
|
||||||
default_settings = OpenAILLMSettings(model="llama-3.3-70b-versatile")
|
default_settings = GroqLLMSettings(model="llama-3.3-70b-versatile")
|
||||||
|
|
||||||
# 2. Apply direct init arg overrides (deprecated)
|
# 2. Apply direct init arg overrides (deprecated)
|
||||||
if model is not None:
|
if model is not None:
|
||||||
_warn_deprecated_param("model", OpenAILLMSettings, "model")
|
_warn_deprecated_param("model", GroqLLMSettings, "model")
|
||||||
default_settings.model = model
|
default_settings.model = model
|
||||||
|
|
||||||
# 4. Apply settings delta (canonical API, always wins)
|
# 4. Apply settings delta (canonical API, always wins)
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
"""Mistral LLM service implementation using OpenAI-compatible interface."""
|
"""Mistral LLM service implementation using OpenAI-compatible interface."""
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
from typing import List, Optional, Sequence
|
from typing import List, Optional, Sequence
|
||||||
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
@@ -18,6 +19,13 @@ from pipecat.services.openai.llm import OpenAILLMService
|
|||||||
from pipecat.services.settings import _warn_deprecated_param
|
from pipecat.services.settings import _warn_deprecated_param
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class MistralLLMSettings(OpenAILLMSettings):
|
||||||
|
"""Settings for Mistral LLM service."""
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class MistralLLMService(OpenAILLMService):
|
class MistralLLMService(OpenAILLMService):
|
||||||
"""A service for interacting with Mistral's API using the OpenAI-compatible interface.
|
"""A service for interacting with Mistral's API using the OpenAI-compatible interface.
|
||||||
|
|
||||||
@@ -31,7 +39,7 @@ class MistralLLMService(OpenAILLMService):
|
|||||||
api_key: str,
|
api_key: str,
|
||||||
base_url: str = "https://api.mistral.ai/v1",
|
base_url: str = "https://api.mistral.ai/v1",
|
||||||
model: Optional[str] = None,
|
model: Optional[str] = None,
|
||||||
settings: Optional[OpenAILLMSettings] = None,
|
settings: Optional[MistralLLMSettings] = None,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
):
|
):
|
||||||
"""Initialize the Mistral LLM service.
|
"""Initialize the Mistral LLM service.
|
||||||
@@ -49,11 +57,11 @@ class MistralLLMService(OpenAILLMService):
|
|||||||
**kwargs: Additional keyword arguments passed to OpenAILLMService.
|
**kwargs: Additional keyword arguments passed to OpenAILLMService.
|
||||||
"""
|
"""
|
||||||
# 1. Initialize default_settings with hardcoded defaults
|
# 1. Initialize default_settings with hardcoded defaults
|
||||||
default_settings = OpenAILLMSettings(model="mistral-small-latest")
|
default_settings = MistralLLMSettings(model="mistral-small-latest")
|
||||||
|
|
||||||
# 2. Apply direct init arg overrides (deprecated)
|
# 2. Apply direct init arg overrides (deprecated)
|
||||||
if model is not None:
|
if model is not None:
|
||||||
_warn_deprecated_param("model", OpenAILLMSettings, "model")
|
_warn_deprecated_param("model", MistralLLMSettings, "model")
|
||||||
default_settings.model = model
|
default_settings.model = model
|
||||||
|
|
||||||
# 4. Apply settings delta (canonical API, always wins)
|
# 4. Apply settings delta (canonical API, always wins)
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ This module provides a service for interacting with NVIDIA's NIM (NVIDIA Inferen
|
|||||||
Microservice) API while maintaining compatibility with the OpenAI-style interface.
|
Microservice) API while maintaining compatibility with the OpenAI-style interface.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from pipecat.metrics.metrics import LLMTokenUsage
|
from pipecat.metrics.metrics import LLMTokenUsage
|
||||||
@@ -20,6 +21,13 @@ from pipecat.services.openai.llm import OpenAILLMService
|
|||||||
from pipecat.services.settings import _warn_deprecated_param
|
from pipecat.services.settings import _warn_deprecated_param
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class NvidiaLLMSettings(OpenAILLMSettings):
|
||||||
|
"""Settings for NVIDIA LLM service."""
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class NvidiaLLMService(OpenAILLMService):
|
class NvidiaLLMService(OpenAILLMService):
|
||||||
"""A service for interacting with NVIDIA's NIM (NVIDIA Inference Microservice) API.
|
"""A service for interacting with NVIDIA's NIM (NVIDIA Inference Microservice) API.
|
||||||
|
|
||||||
@@ -34,7 +42,7 @@ class NvidiaLLMService(OpenAILLMService):
|
|||||||
api_key: str,
|
api_key: str,
|
||||||
base_url: str = "https://integrate.api.nvidia.com/v1",
|
base_url: str = "https://integrate.api.nvidia.com/v1",
|
||||||
model: Optional[str] = None,
|
model: Optional[str] = None,
|
||||||
settings: Optional[OpenAILLMSettings] = None,
|
settings: Optional[NvidiaLLMSettings] = None,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
):
|
):
|
||||||
"""Initialize the NvidiaLLMService.
|
"""Initialize the NvidiaLLMService.
|
||||||
@@ -53,11 +61,11 @@ class NvidiaLLMService(OpenAILLMService):
|
|||||||
**kwargs: Additional keyword arguments passed to OpenAILLMService.
|
**kwargs: Additional keyword arguments passed to OpenAILLMService.
|
||||||
"""
|
"""
|
||||||
# 1. Initialize default_settings with hardcoded defaults
|
# 1. Initialize default_settings with hardcoded defaults
|
||||||
default_settings = OpenAILLMSettings(model="nvidia/llama-3.1-nemotron-70b-instruct")
|
default_settings = NvidiaLLMSettings(model="nvidia/llama-3.1-nemotron-70b-instruct")
|
||||||
|
|
||||||
# 2. Apply direct init arg overrides (deprecated)
|
# 2. Apply direct init arg overrides (deprecated)
|
||||||
if model is not None:
|
if model is not None:
|
||||||
_warn_deprecated_param("model", OpenAILLMSettings, "model")
|
_warn_deprecated_param("model", NvidiaLLMSettings, "model")
|
||||||
default_settings.model = model
|
default_settings.model = model
|
||||||
|
|
||||||
# 4. Apply settings delta (canonical API, always wins)
|
# 4. Apply settings delta (canonical API, always wins)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
from concurrent.futures import CancelledError as FuturesCancelledError
|
from concurrent.futures import CancelledError as FuturesCancelledError
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass, field
|
||||||
from typing import Any, AsyncGenerator, List, Mapping, Optional
|
from typing import Any, AsyncGenerator, List, Mapping, Optional
|
||||||
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
@@ -23,7 +23,7 @@ from pipecat.frames.frames import (
|
|||||||
StartFrame,
|
StartFrame,
|
||||||
TranscriptionFrame,
|
TranscriptionFrame,
|
||||||
)
|
)
|
||||||
from pipecat.services.settings import STTSettings, _warn_deprecated_param
|
from pipecat.services.settings import NOT_GIVEN, STTSettings, _NotGiven, _warn_deprecated_param
|
||||||
from pipecat.services.stt_latency import NVIDIA_TTFS_P99
|
from pipecat.services.stt_latency import NVIDIA_TTFS_P99
|
||||||
from pipecat.services.stt_service import SegmentedSTTService, STTService
|
from pipecat.services.stt_service import SegmentedSTTService, STTService
|
||||||
from pipecat.transcriptions.language import Language, resolve_language
|
from pipecat.transcriptions.language import Language, resolve_language
|
||||||
@@ -110,11 +110,11 @@ class NvidiaSegmentedSTTSettings(STTSettings):
|
|||||||
boosted_lm_score: Score boost for specified words.
|
boosted_lm_score: Score boost for specified words.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
profanity_filter: bool = False
|
profanity_filter: bool | _NotGiven = field(default_factory=lambda: NOT_GIVEN)
|
||||||
automatic_punctuation: bool = True
|
automatic_punctuation: bool | _NotGiven = field(default_factory=lambda: NOT_GIVEN)
|
||||||
verbatim_transcripts: bool = False
|
verbatim_transcripts: bool | _NotGiven = field(default_factory=lambda: NOT_GIVEN)
|
||||||
boosted_lm_words: Optional[List[str]] = None
|
boosted_lm_words: List[str] | None | _NotGiven = field(default_factory=lambda: NOT_GIVEN)
|
||||||
boosted_lm_score: float = 4.0
|
boosted_lm_score: float | _NotGiven = field(default_factory=lambda: NOT_GIVEN)
|
||||||
|
|
||||||
|
|
||||||
class NvidiaSTTService(STTService):
|
class NvidiaSTTService(STTService):
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
"""OLLama LLM service implementation for Pipecat AI framework."""
|
"""OLLama LLM service implementation for Pipecat AI framework."""
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
@@ -15,6 +16,13 @@ from pipecat.services.openai.llm import OpenAILLMService
|
|||||||
from pipecat.services.settings import _warn_deprecated_param
|
from pipecat.services.settings import _warn_deprecated_param
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class OllamaLLMSettings(OpenAILLMSettings):
|
||||||
|
"""Settings for Ollama LLM service."""
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class OLLamaLLMService(OpenAILLMService):
|
class OLLamaLLMService(OpenAILLMService):
|
||||||
"""OLLama LLM service that provides local language model capabilities.
|
"""OLLama LLM service that provides local language model capabilities.
|
||||||
|
|
||||||
@@ -27,7 +35,7 @@ class OLLamaLLMService(OpenAILLMService):
|
|||||||
*,
|
*,
|
||||||
model: Optional[str] = None,
|
model: Optional[str] = None,
|
||||||
base_url: str = "http://localhost:11434/v1",
|
base_url: str = "http://localhost:11434/v1",
|
||||||
settings: Optional[OpenAILLMSettings] = None,
|
settings: Optional[OllamaLLMSettings] = None,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
):
|
):
|
||||||
"""Initialize OLLama LLM service.
|
"""Initialize OLLama LLM service.
|
||||||
@@ -45,11 +53,11 @@ class OLLamaLLMService(OpenAILLMService):
|
|||||||
**kwargs: Additional keyword arguments passed to OpenAILLMService.
|
**kwargs: Additional keyword arguments passed to OpenAILLMService.
|
||||||
"""
|
"""
|
||||||
# 1. Initialize default_settings with hardcoded defaults
|
# 1. Initialize default_settings with hardcoded defaults
|
||||||
default_settings = OpenAILLMSettings(model="llama2")
|
default_settings = OllamaLLMSettings(model="llama2")
|
||||||
|
|
||||||
# 2. Apply direct init arg overrides (deprecated)
|
# 2. Apply direct init arg overrides (deprecated)
|
||||||
if model is not None:
|
if model is not None:
|
||||||
_warn_deprecated_param("model", OpenAILLMSettings, "model")
|
_warn_deprecated_param("model", OllamaLLMSettings, "model")
|
||||||
default_settings.model = model
|
default_settings.model = model
|
||||||
|
|
||||||
# 4. Apply settings delta (canonical API, always wins)
|
# 4. Apply settings delta (canonical API, always wins)
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ Provides two STT services:
|
|||||||
|
|
||||||
import base64
|
import base64
|
||||||
import json
|
import json
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass, field
|
||||||
from typing import Any, AsyncGenerator, Literal, Optional, Union
|
from typing import Any, AsyncGenerator, Literal, Optional, Union
|
||||||
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
@@ -35,7 +35,7 @@ from pipecat.frames.frames import (
|
|||||||
VADUserStoppedSpeakingFrame,
|
VADUserStoppedSpeakingFrame,
|
||||||
)
|
)
|
||||||
from pipecat.processors.frame_processor import FrameDirection
|
from pipecat.processors.frame_processor import FrameDirection
|
||||||
from pipecat.services.settings import STTSettings, _NotGiven, _warn_deprecated_param
|
from pipecat.services.settings import NOT_GIVEN, STTSettings, _NotGiven, _warn_deprecated_param
|
||||||
from pipecat.services.stt_latency import OPENAI_REALTIME_TTFS_P99, OPENAI_TTFS_P99
|
from pipecat.services.stt_latency import OPENAI_REALTIME_TTFS_P99, OPENAI_TTFS_P99
|
||||||
from pipecat.services.stt_service import WebsocketSTTService
|
from pipecat.services.stt_service import WebsocketSTTService
|
||||||
from pipecat.services.whisper.base_stt import (
|
from pipecat.services.whisper.base_stt import (
|
||||||
@@ -188,7 +188,7 @@ class OpenAIRealtimeSTTSettings(STTSettings):
|
|||||||
prompt: Optional prompt text to guide transcription style.
|
prompt: Optional prompt text to guide transcription style.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
prompt: str | None | _NotGiven = None
|
prompt: str | None | _NotGiven = field(default_factory=lambda: NOT_GIVEN)
|
||||||
|
|
||||||
|
|
||||||
class OpenAIRealtimeSTTService(WebsocketSTTService):
|
class OpenAIRealtimeSTTService(WebsocketSTTService):
|
||||||
|
|||||||
@@ -7,10 +7,11 @@
|
|||||||
"""Azure OpenAI Realtime Beta LLM service implementation."""
|
"""Azure OpenAI Realtime Beta LLM service implementation."""
|
||||||
|
|
||||||
import warnings
|
import warnings
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
|
||||||
from .openai import OpenAIRealtimeBetaLLMService
|
from .openai import OpenAIRealtimeBetaLLMService, OpenAIRealtimeBetaLLMSettings
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from websockets.asyncio.client import connect as websocket_connect
|
from websockets.asyncio.client import connect as websocket_connect
|
||||||
@@ -22,6 +23,13 @@ except ModuleNotFoundError as e:
|
|||||||
raise Exception(f"Missing module: {e}")
|
raise Exception(f"Missing module: {e}")
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class AzureRealtimeBetaLLMSettings(OpenAIRealtimeBetaLLMSettings):
|
||||||
|
"""Settings for Azure Realtime Beta LLM service."""
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class AzureRealtimeBetaLLMService(OpenAIRealtimeBetaLLMService):
|
class AzureRealtimeBetaLLMService(OpenAIRealtimeBetaLLMService):
|
||||||
"""Azure OpenAI Realtime Beta LLM service with Azure-specific authentication.
|
"""Azure OpenAI Realtime Beta LLM service with Azure-specific authentication.
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ This module provides an OpenPipe-specific implementation of the OpenAI LLM servi
|
|||||||
enabling integration with OpenPipe's fine-tuning and monitoring capabilities.
|
enabling integration with OpenPipe's fine-tuning and monitoring capabilities.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
from typing import Dict, Optional
|
from typing import Dict, Optional
|
||||||
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
@@ -27,6 +28,13 @@ except ModuleNotFoundError as e:
|
|||||||
raise Exception(f"Missing module: {e}")
|
raise Exception(f"Missing module: {e}")
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class OpenPipeLLMSettings(OpenAILLMSettings):
|
||||||
|
"""Settings for OpenPipe LLM service."""
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class OpenPipeLLMService(OpenAILLMService):
|
class OpenPipeLLMService(OpenAILLMService):
|
||||||
"""OpenPipe-powered Large Language Model service.
|
"""OpenPipe-powered Large Language Model service.
|
||||||
|
|
||||||
@@ -44,7 +52,7 @@ class OpenPipeLLMService(OpenAILLMService):
|
|||||||
openpipe_api_key: Optional[str] = None,
|
openpipe_api_key: Optional[str] = None,
|
||||||
openpipe_base_url: str = "https://app.openpipe.ai/api/v1",
|
openpipe_base_url: str = "https://app.openpipe.ai/api/v1",
|
||||||
tags: Optional[Dict[str, str]] = None,
|
tags: Optional[Dict[str, str]] = None,
|
||||||
settings: Optional[OpenAILLMSettings] = None,
|
settings: Optional[OpenPipeLLMSettings] = None,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
):
|
):
|
||||||
"""Initialize OpenPipe LLM service.
|
"""Initialize OpenPipe LLM service.
|
||||||
@@ -65,11 +73,11 @@ class OpenPipeLLMService(OpenAILLMService):
|
|||||||
**kwargs: Additional arguments passed to parent OpenAILLMService.
|
**kwargs: Additional arguments passed to parent OpenAILLMService.
|
||||||
"""
|
"""
|
||||||
# 1. Initialize default_settings with hardcoded defaults
|
# 1. Initialize default_settings with hardcoded defaults
|
||||||
default_settings = OpenAILLMSettings(model="gpt-4.1")
|
default_settings = OpenPipeLLMSettings(model="gpt-4.1")
|
||||||
|
|
||||||
# 2. Apply direct init arg overrides (deprecated)
|
# 2. Apply direct init arg overrides (deprecated)
|
||||||
if model is not None:
|
if model is not None:
|
||||||
_warn_deprecated_param("model", OpenAILLMSettings, "model")
|
_warn_deprecated_param("model", OpenPipeLLMSettings, "model")
|
||||||
default_settings.model = model
|
default_settings.model = model
|
||||||
|
|
||||||
# 4. Apply settings delta (canonical API, always wins)
|
# 4. Apply settings delta (canonical API, always wins)
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ This module provides an OpenAI-compatible interface for interacting with OpenRou
|
|||||||
extending the base OpenAI LLM service functionality.
|
extending the base OpenAI LLM service functionality.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
from typing import Any, Dict, Optional
|
from typing import Any, Dict, Optional
|
||||||
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
@@ -19,6 +20,13 @@ from pipecat.services.openai.llm import OpenAILLMService
|
|||||||
from pipecat.services.settings import _warn_deprecated_param
|
from pipecat.services.settings import _warn_deprecated_param
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class OpenRouterLLMSettings(OpenAILLMSettings):
|
||||||
|
"""Settings for OpenRouter LLM service."""
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class OpenRouterLLMService(OpenAILLMService):
|
class OpenRouterLLMService(OpenAILLMService):
|
||||||
"""A service for interacting with OpenRouter's API using the OpenAI-compatible interface.
|
"""A service for interacting with OpenRouter's API using the OpenAI-compatible interface.
|
||||||
|
|
||||||
@@ -32,7 +40,7 @@ class OpenRouterLLMService(OpenAILLMService):
|
|||||||
api_key: Optional[str] = None,
|
api_key: Optional[str] = None,
|
||||||
model: Optional[str] = None,
|
model: Optional[str] = None,
|
||||||
base_url: str = "https://openrouter.ai/api/v1",
|
base_url: str = "https://openrouter.ai/api/v1",
|
||||||
settings: Optional[OpenAILLMSettings] = None,
|
settings: Optional[OpenRouterLLMSettings] = None,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
):
|
):
|
||||||
"""Initialize the OpenRouter LLM service.
|
"""Initialize the OpenRouter LLM service.
|
||||||
@@ -51,11 +59,11 @@ class OpenRouterLLMService(OpenAILLMService):
|
|||||||
**kwargs: Additional keyword arguments passed to OpenAILLMService.
|
**kwargs: Additional keyword arguments passed to OpenAILLMService.
|
||||||
"""
|
"""
|
||||||
# 1. Initialize default_settings with hardcoded defaults
|
# 1. Initialize default_settings with hardcoded defaults
|
||||||
default_settings = OpenAILLMSettings(model="openai/gpt-4o-2024-11-20")
|
default_settings = OpenRouterLLMSettings(model="openai/gpt-4o-2024-11-20")
|
||||||
|
|
||||||
# 2. Apply direct init arg overrides (deprecated)
|
# 2. Apply direct init arg overrides (deprecated)
|
||||||
if model is not None:
|
if model is not None:
|
||||||
_warn_deprecated_param("model", OpenAILLMSettings, "model")
|
_warn_deprecated_param("model", OpenRouterLLMSettings, "model")
|
||||||
default_settings.model = model
|
default_settings.model = model
|
||||||
|
|
||||||
# 4. Apply settings delta (canonical API, always wins)
|
# 4. Apply settings delta (canonical API, always wins)
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ an OpenAI-compatible interface. It handles Perplexity's unique token usage
|
|||||||
reporting patterns while maintaining compatibility with the Pipecat framework.
|
reporting patterns while maintaining compatibility with the Pipecat framework.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from pipecat.adapters.services.open_ai_adapter import OpenAILLMInvocationParams
|
from pipecat.adapters.services.open_ai_adapter import OpenAILLMInvocationParams
|
||||||
@@ -22,6 +23,13 @@ from pipecat.services.openai.llm import OpenAILLMService
|
|||||||
from pipecat.services.settings import _warn_deprecated_param
|
from pipecat.services.settings import _warn_deprecated_param
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class PerplexityLLMSettings(OpenAILLMSettings):
|
||||||
|
"""Settings for Perplexity LLM service."""
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class PerplexityLLMService(OpenAILLMService):
|
class PerplexityLLMService(OpenAILLMService):
|
||||||
"""A service for interacting with Perplexity's API.
|
"""A service for interacting with Perplexity's API.
|
||||||
|
|
||||||
@@ -36,7 +44,7 @@ class PerplexityLLMService(OpenAILLMService):
|
|||||||
api_key: str,
|
api_key: str,
|
||||||
base_url: str = "https://api.perplexity.ai",
|
base_url: str = "https://api.perplexity.ai",
|
||||||
model: Optional[str] = None,
|
model: Optional[str] = None,
|
||||||
settings: Optional[OpenAILLMSettings] = None,
|
settings: Optional[PerplexityLLMSettings] = None,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
):
|
):
|
||||||
"""Initialize the Perplexity LLM service.
|
"""Initialize the Perplexity LLM service.
|
||||||
@@ -54,11 +62,11 @@ class PerplexityLLMService(OpenAILLMService):
|
|||||||
**kwargs: Additional keyword arguments passed to OpenAILLMService.
|
**kwargs: Additional keyword arguments passed to OpenAILLMService.
|
||||||
"""
|
"""
|
||||||
# 1. Initialize default_settings with hardcoded defaults
|
# 1. Initialize default_settings with hardcoded defaults
|
||||||
default_settings = OpenAILLMSettings(model="sonar")
|
default_settings = PerplexityLLMSettings(model="sonar")
|
||||||
|
|
||||||
# 2. Apply direct init arg overrides (deprecated)
|
# 2. Apply direct init arg overrides (deprecated)
|
||||||
if model is not None:
|
if model is not None:
|
||||||
_warn_deprecated_param("model", OpenAILLMSettings, "model")
|
_warn_deprecated_param("model", PerplexityLLMSettings, "model")
|
||||||
default_settings.model = model
|
default_settings.model = model
|
||||||
|
|
||||||
# 4. Apply settings delta (canonical API, always wins)
|
# 4. Apply settings delta (canonical API, always wins)
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
"""Qwen LLM service implementation using OpenAI-compatible interface."""
|
"""Qwen LLM service implementation using OpenAI-compatible interface."""
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
@@ -15,6 +16,13 @@ from pipecat.services.openai.llm import OpenAILLMService
|
|||||||
from pipecat.services.settings import _warn_deprecated_param
|
from pipecat.services.settings import _warn_deprecated_param
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class QwenLLMSettings(OpenAILLMSettings):
|
||||||
|
"""Settings for Qwen LLM service."""
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class QwenLLMService(OpenAILLMService):
|
class QwenLLMService(OpenAILLMService):
|
||||||
"""A service for interacting with Alibaba Cloud's Qwen LLM API using the OpenAI-compatible interface.
|
"""A service for interacting with Alibaba Cloud's Qwen LLM API using the OpenAI-compatible interface.
|
||||||
|
|
||||||
@@ -28,7 +36,7 @@ class QwenLLMService(OpenAILLMService):
|
|||||||
api_key: str,
|
api_key: str,
|
||||||
base_url: str = "https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
|
base_url: str = "https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
|
||||||
model: Optional[str] = None,
|
model: Optional[str] = None,
|
||||||
settings: Optional[OpenAILLMSettings] = None,
|
settings: Optional[QwenLLMSettings] = None,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
):
|
):
|
||||||
"""Initialize the Qwen LLM service.
|
"""Initialize the Qwen LLM service.
|
||||||
@@ -46,11 +54,11 @@ class QwenLLMService(OpenAILLMService):
|
|||||||
**kwargs: Additional keyword arguments passed to OpenAILLMService.
|
**kwargs: Additional keyword arguments passed to OpenAILLMService.
|
||||||
"""
|
"""
|
||||||
# 1. Initialize default_settings with hardcoded defaults
|
# 1. Initialize default_settings with hardcoded defaults
|
||||||
default_settings = OpenAILLMSettings(model="qwen-plus")
|
default_settings = QwenLLMSettings(model="qwen-plus")
|
||||||
|
|
||||||
# 2. Apply direct init arg overrides (deprecated)
|
# 2. Apply direct init arg overrides (deprecated)
|
||||||
if model is not None:
|
if model is not None:
|
||||||
_warn_deprecated_param("model", OpenAILLMSettings, "model")
|
_warn_deprecated_param("model", QwenLLMSettings, "model")
|
||||||
default_settings.model = model
|
default_settings.model = model
|
||||||
|
|
||||||
# 4. Apply settings delta (canonical API, always wins)
|
# 4. Apply settings delta (canonical API, always wins)
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
"""SambaNova LLM service implementation using OpenAI-compatible interface."""
|
"""SambaNova LLM service implementation using OpenAI-compatible interface."""
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
from dataclasses import dataclass
|
||||||
from typing import Any, Dict, Optional
|
from typing import Any, Dict, Optional
|
||||||
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
@@ -27,6 +28,13 @@ from pipecat.services.settings import _warn_deprecated_param
|
|||||||
from pipecat.utils.tracing.service_decorators import traced_llm
|
from pipecat.utils.tracing.service_decorators import traced_llm
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class SambaNovaLLMSettings(OpenAILLMSettings):
|
||||||
|
"""Settings for SambaNova LLM service."""
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class SambaNovaLLMService(OpenAILLMService): # type: ignore
|
class SambaNovaLLMService(OpenAILLMService): # type: ignore
|
||||||
"""A service for interacting with SambaNova using the OpenAI-compatible interface.
|
"""A service for interacting with SambaNova using the OpenAI-compatible interface.
|
||||||
|
|
||||||
@@ -40,7 +48,7 @@ class SambaNovaLLMService(OpenAILLMService): # type: ignore
|
|||||||
api_key: str,
|
api_key: str,
|
||||||
model: Optional[str] = None,
|
model: Optional[str] = None,
|
||||||
base_url: str = "https://api.sambanova.ai/v1",
|
base_url: str = "https://api.sambanova.ai/v1",
|
||||||
settings: Optional[OpenAILLMSettings] = None,
|
settings: Optional[SambaNovaLLMSettings] = None,
|
||||||
**kwargs: Dict[Any, Any],
|
**kwargs: Dict[Any, Any],
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize SambaNova LLM service.
|
"""Initialize SambaNova LLM service.
|
||||||
@@ -58,11 +66,11 @@ class SambaNovaLLMService(OpenAILLMService): # type: ignore
|
|||||||
**kwargs: Additional keyword arguments passed to OpenAILLMService.
|
**kwargs: Additional keyword arguments passed to OpenAILLMService.
|
||||||
"""
|
"""
|
||||||
# 1. Initialize default_settings with hardcoded defaults
|
# 1. Initialize default_settings with hardcoded defaults
|
||||||
default_settings = OpenAILLMSettings(model="Llama-4-Maverick-17B-128E-Instruct")
|
default_settings = SambaNovaLLMSettings(model="Llama-4-Maverick-17B-128E-Instruct")
|
||||||
|
|
||||||
# 2. Apply direct init arg overrides (deprecated)
|
# 2. Apply direct init arg overrides (deprecated)
|
||||||
if model is not None:
|
if model is not None:
|
||||||
_warn_deprecated_param("model", OpenAILLMSettings, "model")
|
_warn_deprecated_param("model", SambaNovaLLMSettings, "model")
|
||||||
default_settings.model = model
|
default_settings.model = model
|
||||||
|
|
||||||
# 4. Apply settings delta (canonical API, always wins)
|
# 4. Apply settings delta (canonical API, always wins)
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
"""Together.ai LLM service implementation using OpenAI-compatible interface."""
|
"""Together.ai LLM service implementation using OpenAI-compatible interface."""
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
@@ -15,6 +16,13 @@ from pipecat.services.openai.llm import OpenAILLMService
|
|||||||
from pipecat.services.settings import _warn_deprecated_param
|
from pipecat.services.settings import _warn_deprecated_param
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class TogetherLLMSettings(OpenAILLMSettings):
|
||||||
|
"""Settings for Together LLM service."""
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class TogetherLLMService(OpenAILLMService):
|
class TogetherLLMService(OpenAILLMService):
|
||||||
"""A service for interacting with Together.ai's API using the OpenAI-compatible interface.
|
"""A service for interacting with Together.ai's API using the OpenAI-compatible interface.
|
||||||
|
|
||||||
@@ -28,7 +36,7 @@ class TogetherLLMService(OpenAILLMService):
|
|||||||
api_key: str,
|
api_key: str,
|
||||||
base_url: str = "https://api.together.xyz/v1",
|
base_url: str = "https://api.together.xyz/v1",
|
||||||
model: Optional[str] = None,
|
model: Optional[str] = None,
|
||||||
settings: Optional[OpenAILLMSettings] = None,
|
settings: Optional[TogetherLLMSettings] = None,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
):
|
):
|
||||||
"""Initialize Together.ai LLM service.
|
"""Initialize Together.ai LLM service.
|
||||||
@@ -46,11 +54,11 @@ class TogetherLLMService(OpenAILLMService):
|
|||||||
**kwargs: Additional keyword arguments passed to OpenAILLMService.
|
**kwargs: Additional keyword arguments passed to OpenAILLMService.
|
||||||
"""
|
"""
|
||||||
# 1. Initialize default_settings with hardcoded defaults
|
# 1. Initialize default_settings with hardcoded defaults
|
||||||
default_settings = OpenAILLMSettings(model="meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo")
|
default_settings = TogetherLLMSettings(model="meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo")
|
||||||
|
|
||||||
# 2. Apply direct init arg overrides (deprecated)
|
# 2. Apply direct init arg overrides (deprecated)
|
||||||
if model is not None:
|
if model is not None:
|
||||||
_warn_deprecated_param("model", OpenAILLMSettings, "model")
|
_warn_deprecated_param("model", TogetherLLMSettings, "model")
|
||||||
default_settings.model = model
|
default_settings.model = model
|
||||||
|
|
||||||
# 4. Apply settings delta (canonical API, always wins)
|
# 4. Apply settings delta (canonical API, always wins)
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ This module provides common functionality for services implementing the Whisper
|
|||||||
interface, including language mapping, metrics generation, and error handling.
|
interface, including language mapping, metrics generation, and error handling.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass, field
|
||||||
from typing import AsyncGenerator, Optional
|
from typing import AsyncGenerator, Optional
|
||||||
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
@@ -18,7 +18,7 @@ from openai import AsyncOpenAI
|
|||||||
from openai.types.audio import Transcription
|
from openai.types.audio import Transcription
|
||||||
|
|
||||||
from pipecat.frames.frames import ErrorFrame, Frame, TranscriptionFrame
|
from pipecat.frames.frames import ErrorFrame, Frame, TranscriptionFrame
|
||||||
from pipecat.services.settings import STTSettings, _NotGiven, _warn_deprecated_param
|
from pipecat.services.settings import NOT_GIVEN, STTSettings, _NotGiven, _warn_deprecated_param
|
||||||
from pipecat.services.stt_latency import WHISPER_TTFS_P99
|
from pipecat.services.stt_latency import WHISPER_TTFS_P99
|
||||||
from pipecat.services.stt_service import SegmentedSTTService
|
from pipecat.services.stt_service import SegmentedSTTService
|
||||||
from pipecat.transcriptions.language import Language, resolve_language
|
from pipecat.transcriptions.language import Language, resolve_language
|
||||||
@@ -36,8 +36,8 @@ class BaseWhisperSTTSettings(STTSettings):
|
|||||||
temperature: Sampling temperature between 0 and 1.
|
temperature: Sampling temperature between 0 and 1.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
prompt: str | None | _NotGiven = None
|
prompt: str | None | _NotGiven = field(default_factory=lambda: NOT_GIVEN)
|
||||||
temperature: float | None | _NotGiven = None
|
temperature: float | None | _NotGiven = field(default_factory=lambda: NOT_GIVEN)
|
||||||
|
|
||||||
|
|
||||||
def language_to_whisper_language(language: Language) -> Optional[str]:
|
def language_to_whisper_language(language: Language) -> Optional[str]:
|
||||||
@@ -183,6 +183,8 @@ class BaseWhisperSTTService(SegmentedSTTService):
|
|||||||
default_settings = BaseWhisperSTTSettings(
|
default_settings = BaseWhisperSTTSettings(
|
||||||
model=None,
|
model=None,
|
||||||
language=None,
|
language=None,
|
||||||
|
prompt=None,
|
||||||
|
temperature=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
# --- 2. Deprecated direct-arg overrides ---
|
# --- 2. Deprecated direct-arg overrides ---
|
||||||
|
|||||||
181
tests/test_service_init.py
Normal file
181
tests/test_service_init.py
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
#
|
||||||
|
# Copyright (c) 2024-2026, Daily
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: BSD 2-Clause License
|
||||||
|
#
|
||||||
|
|
||||||
|
"""Tests for service settings and initialization patterns.
|
||||||
|
|
||||||
|
Settings objects operate in two modes:
|
||||||
|
|
||||||
|
- **Store mode** (``self._settings``): the live state inside a service.
|
||||||
|
Every field must hold a real value (``None`` is fine, ``NOT_GIVEN`` is not).
|
||||||
|
- **Delta mode** (``FooSettings()`` with no args): a sparse update.
|
||||||
|
Every field must default to ``NOT_GIVEN`` so ``apply_update()`` skips
|
||||||
|
untouched fields and doesn't accidentally overwrite the store.
|
||||||
|
|
||||||
|
These tests verify both sides of that contract automatically:
|
||||||
|
|
||||||
|
1. **Delta defaults** — Instantiate every ``ServiceSettings`` subclass with
|
||||||
|
no arguments and assert that every field is ``NOT_GIVEN``. Catches the
|
||||||
|
bug where a field defaults to ``None`` instead of ``NOT_GIVEN``, which
|
||||||
|
would cause partial deltas to silently overwrite unrelated store values.
|
||||||
|
|
||||||
|
2. **Store completeness** — Instantiate every concrete service with dummy
|
||||||
|
args and assert that ``_settings`` contains no ``NOT_GIVEN`` values.
|
||||||
|
This is the same check that ``validate_complete()`` runs in ``start()``,
|
||||||
|
but caught here at unit-test time without needing a running pipeline.
|
||||||
|
Catches services that forget to initialize a field in ``default_settings``.
|
||||||
|
|
||||||
|
All Settings and Service classes are auto-discovered via ``pkgutil``;
|
||||||
|
new services are covered automatically with no per-service maintenance.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import importlib
|
||||||
|
import inspect
|
||||||
|
import pkgutil
|
||||||
|
import warnings
|
||||||
|
from dataclasses import fields
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
import pipecat.services
|
||||||
|
from pipecat.services.ai_service import AIService
|
||||||
|
from pipecat.services.settings import ServiceSettings, is_given
|
||||||
|
|
||||||
|
# Modules that define abstract base service classes (not concrete services).
|
||||||
|
_BASE_MODULES = frozenset(
|
||||||
|
{
|
||||||
|
"pipecat.services.ai_service",
|
||||||
|
"pipecat.services.llm_service",
|
||||||
|
"pipecat.services.stt_service",
|
||||||
|
"pipecat.services.tts_service",
|
||||||
|
"pipecat.services.image_gen_service",
|
||||||
|
"pipecat.services.vision_service",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Auto-discovery
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
def _all_subclasses(cls):
|
||||||
|
result = set()
|
||||||
|
for sub in cls.__subclasses__():
|
||||||
|
result.add(sub)
|
||||||
|
result.update(_all_subclasses(sub))
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def _import_all_service_modules():
|
||||||
|
"""Import every module under pipecat.services (skipping missing deps)."""
|
||||||
|
package = pipecat.services
|
||||||
|
for _importer, modname, _ispkg in pkgutil.walk_packages(
|
||||||
|
package.__path__, prefix=package.__name__ + "."
|
||||||
|
):
|
||||||
|
try:
|
||||||
|
importlib.import_module(modname)
|
||||||
|
except Exception:
|
||||||
|
continue
|
||||||
|
|
||||||
|
|
||||||
|
_import_all_service_modules()
|
||||||
|
|
||||||
|
ALL_SETTINGS_CLASSES = sorted(_all_subclasses(ServiceSettings), key=lambda c: c.__qualname__)
|
||||||
|
assert ALL_SETTINGS_CLASSES, "No settings classes discovered"
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Service instantiation helpers
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
def _try_instantiate(cls):
|
||||||
|
"""Try to instantiate a service with dummy values for required args.
|
||||||
|
|
||||||
|
Inspects the __init__ signature and passes "test" for every required
|
||||||
|
keyword-only parameter. Services that need non-string required args
|
||||||
|
or fail for other reasons will raise and be skipped by the test.
|
||||||
|
"""
|
||||||
|
sig = inspect.signature(cls.__init__)
|
||||||
|
kwargs = {}
|
||||||
|
for name, param in sig.parameters.items():
|
||||||
|
if name == "self":
|
||||||
|
continue
|
||||||
|
if param.kind in (param.VAR_POSITIONAL, param.VAR_KEYWORD):
|
||||||
|
continue
|
||||||
|
if param.default is not param.empty:
|
||||||
|
continue
|
||||||
|
# Required parameter — pass a dummy string
|
||||||
|
kwargs[name] = "test"
|
||||||
|
return cls(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def _discover_service_classes():
|
||||||
|
"""Return concrete service classes that can be instantiated with dummy args."""
|
||||||
|
result = []
|
||||||
|
for cls in sorted(_all_subclasses(AIService), key=lambda c: c.__qualname__):
|
||||||
|
# Skip abstract base classes defined in framework modules.
|
||||||
|
if cls.__module__ in _BASE_MODULES:
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
svc = _try_instantiate(cls)
|
||||||
|
except Exception:
|
||||||
|
continue
|
||||||
|
if hasattr(svc, "_settings"):
|
||||||
|
result.append(cls)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
ALL_SERVICE_CLASSES = _discover_service_classes()
|
||||||
|
assert ALL_SERVICE_CLASSES, "No service classes could be instantiated"
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# 1. Settings defaults: delta-mode safety
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("settings_cls", ALL_SETTINGS_CLASSES, ids=lambda c: c.__qualname__)
|
||||||
|
def test_delta_defaults_are_not_given(settings_cls):
|
||||||
|
"""Every field must default to NOT_GIVEN so empty deltas are no-ops.
|
||||||
|
|
||||||
|
A field that defaults to None instead of NOT_GIVEN will cause
|
||||||
|
apply_update() to overwrite the corresponding store value whenever
|
||||||
|
a partial delta is applied.
|
||||||
|
"""
|
||||||
|
instance = settings_cls()
|
||||||
|
for f in fields(instance):
|
||||||
|
if f.name == "extra":
|
||||||
|
continue
|
||||||
|
val = getattr(instance, f.name)
|
||||||
|
assert not is_given(val), (
|
||||||
|
f"{settings_cls.__qualname__}.{f.name} defaults to {val!r}, expected NOT_GIVEN"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# 2. Service construction: store-mode completeness
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("service_cls", ALL_SERVICE_CLASSES, ids=lambda c: c.__qualname__)
|
||||||
|
def test_service_settings_complete(service_cls):
|
||||||
|
"""After construction, _settings must have no NOT_GIVEN values.
|
||||||
|
|
||||||
|
This is what validate_complete() checks in start(). Catching it
|
||||||
|
here means we don't need a running pipeline to find missing defaults.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
svc = _try_instantiate(service_cls)
|
||||||
|
except Exception:
|
||||||
|
pytest.skip("Cannot re-instantiate (environment issue)")
|
||||||
|
for f in fields(svc._settings):
|
||||||
|
if f.name == "extra":
|
||||||
|
continue
|
||||||
|
val = getattr(svc._settings, f.name)
|
||||||
|
assert is_given(val), (
|
||||||
|
f"{service_cls.__qualname__}._settings.{f.name} is NOT_GIVEN after construction"
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user