Consolidate service UpdateSettingsFrame into a single ServiceUpdateSettingsFrame
This commit is contained in:
@@ -86,8 +86,8 @@ async def on_connected(processor):
|
|||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Updated individual update settings frame classes into a single UpdateSettingsFrame
|
- Updated individual update settings frame classes into a single
|
||||||
class for STT, LLM, and TTS.
|
ServiceUpdateSettingsFrame class.
|
||||||
|
|
||||||
- We now distinguish between input and output audio and image frames. We
|
- We now distinguish between input and output audio and image frames. We
|
||||||
introduce `InputAudioRawFrame`, `OutputAudioRawFrame`, `InputImageRawFrame`
|
introduce `InputAudioRawFrame`, `OutputAudioRawFrame`, `InputImageRawFrame`
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
from typing import Any, List, Optional, Tuple, Union
|
from typing import Any, Dict, List, Optional, Tuple
|
||||||
|
|
||||||
from pipecat.clocks.base_clock import BaseClock
|
from pipecat.clocks.base_clock import BaseClock
|
||||||
from pipecat.metrics.metrics import MetricsData
|
from pipecat.metrics.metrics import MetricsData
|
||||||
@@ -527,47 +527,11 @@ class UserImageRequestFrame(ControlFrame):
|
|||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class LLMUpdateSettingsFrame(ControlFrame):
|
class ServiceUpdateSettingsFrame(ControlFrame):
|
||||||
"""A control frame containing a request to update LLM settings."""
|
"""A control frame containing a request to update service settings."""
|
||||||
|
|
||||||
model: Optional[str] = None
|
service_type: str
|
||||||
temperature: Optional[float] = None
|
settings: Dict[str, Any]
|
||||||
top_k: Optional[int] = None
|
|
||||||
top_p: Optional[float] = None
|
|
||||||
frequency_penalty: Optional[float] = None
|
|
||||||
presence_penalty: Optional[float] = None
|
|
||||||
max_tokens: Optional[int] = None
|
|
||||||
seed: Optional[int] = None
|
|
||||||
extra: dict = field(default_factory=dict)
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class TTSUpdateSettingsFrame(ControlFrame):
|
|
||||||
"""A control frame containing a request to update TTS settings."""
|
|
||||||
|
|
||||||
model: Optional[str] = None
|
|
||||||
voice: Optional[str] = None
|
|
||||||
language: Optional[Language] = None
|
|
||||||
speed: Optional[Union[str, float]] = None
|
|
||||||
emotion: Optional[List[str]] = None
|
|
||||||
engine: Optional[str] = None
|
|
||||||
pitch: Optional[str] = None
|
|
||||||
rate: Optional[str] = None
|
|
||||||
volume: Optional[str] = None
|
|
||||||
emphasis: Optional[str] = None
|
|
||||||
style: Optional[str] = None
|
|
||||||
style_degree: Optional[str] = None
|
|
||||||
role: Optional[str] = None
|
|
||||||
gender: Optional[str] = None
|
|
||||||
google_style: Optional[str] = None
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class STTUpdateSettingsFrame(ControlFrame):
|
|
||||||
"""A control frame containing a request to update STT settings."""
|
|
||||||
|
|
||||||
model: Optional[str] = None
|
|
||||||
language: Optional[Language] = None
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import asyncio
|
|||||||
import io
|
import io
|
||||||
import wave
|
import wave
|
||||||
from abc import abstractmethod
|
from abc import abstractmethod
|
||||||
from typing import AsyncGenerator, List, Optional, Tuple, Union
|
from typing import Any, AsyncGenerator, Dict, List, Optional, Tuple, Union
|
||||||
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
|
||||||
@@ -19,15 +19,14 @@ from pipecat.frames.frames import (
|
|||||||
ErrorFrame,
|
ErrorFrame,
|
||||||
Frame,
|
Frame,
|
||||||
LLMFullResponseEndFrame,
|
LLMFullResponseEndFrame,
|
||||||
|
ServiceUpdateSettingsFrame,
|
||||||
StartFrame,
|
StartFrame,
|
||||||
StartInterruptionFrame,
|
StartInterruptionFrame,
|
||||||
STTUpdateSettingsFrame,
|
|
||||||
TextFrame,
|
TextFrame,
|
||||||
TTSAudioRawFrame,
|
TTSAudioRawFrame,
|
||||||
TTSSpeakFrame,
|
TTSSpeakFrame,
|
||||||
TTSStartedFrame,
|
TTSStartedFrame,
|
||||||
TTSStoppedFrame,
|
TTSStoppedFrame,
|
||||||
TTSUpdateSettingsFrame,
|
|
||||||
UserImageRequestFrame,
|
UserImageRequestFrame,
|
||||||
VisionImageRawFrame,
|
VisionImageRawFrame,
|
||||||
)
|
)
|
||||||
@@ -169,6 +168,7 @@ class TTSService(AIService):
|
|||||||
self._push_stop_frames: bool = push_stop_frames
|
self._push_stop_frames: bool = push_stop_frames
|
||||||
self._stop_frame_timeout_s: float = stop_frame_timeout_s
|
self._stop_frame_timeout_s: float = stop_frame_timeout_s
|
||||||
self._sample_rate: int = sample_rate
|
self._sample_rate: int = sample_rate
|
||||||
|
self._settings: Dict[str, Any] = {}
|
||||||
|
|
||||||
self._stop_frame_task: Optional[asyncio.Task] = None
|
self._stop_frame_task: Optional[asyncio.Task] = None
|
||||||
self._stop_frame_queue: asyncio.Queue = asyncio.Queue()
|
self._stop_frame_queue: asyncio.Queue = asyncio.Queue()
|
||||||
@@ -231,10 +231,6 @@ class TTSService(AIService):
|
|||||||
async def set_role(self, role: str):
|
async def set_role(self, role: str):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
async def flush_audio(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def set_gender(self, gender: str):
|
async def set_gender(self, gender: str):
|
||||||
pass
|
pass
|
||||||
@@ -243,6 +239,10 @@ class TTSService(AIService):
|
|||||||
async def set_google_style(self, google_style: str):
|
async def set_google_style(self, google_style: str):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
async def flush_audio(self):
|
||||||
|
pass
|
||||||
|
|
||||||
# Converts the text to audio.
|
# Converts the text to audio.
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def run_tts(self, text: str) -> AsyncGenerator[Frame, None]:
|
async def run_tts(self, text: str) -> AsyncGenerator[Frame, None]:
|
||||||
@@ -267,6 +267,22 @@ class TTSService(AIService):
|
|||||||
await self._stop_frame_task
|
await self._stop_frame_task
|
||||||
self._stop_frame_task = None
|
self._stop_frame_task = None
|
||||||
|
|
||||||
|
async def _update_settings(self, settings: Dict[str, Any]):
|
||||||
|
for key, value in settings.items():
|
||||||
|
setter = getattr(self, f"set_{key}", None)
|
||||||
|
if setter and callable(setter):
|
||||||
|
try:
|
||||||
|
if key == "language":
|
||||||
|
await setter(Language(value))
|
||||||
|
else:
|
||||||
|
await setter(value)
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"Error setting {key}: {e}")
|
||||||
|
else:
|
||||||
|
logger.warning(f"Unknown setting for TTS service: {key}")
|
||||||
|
|
||||||
|
self._settings.update(settings)
|
||||||
|
|
||||||
async def say(self, text: str):
|
async def say(self, text: str):
|
||||||
aggregate_sentences = self._aggregate_sentences
|
aggregate_sentences = self._aggregate_sentences
|
||||||
self._aggregate_sentences = False
|
self._aggregate_sentences = False
|
||||||
@@ -293,8 +309,8 @@ class TTSService(AIService):
|
|||||||
elif isinstance(frame, TTSSpeakFrame):
|
elif isinstance(frame, TTSSpeakFrame):
|
||||||
await self._push_tts_frames(frame.text)
|
await self._push_tts_frames(frame.text)
|
||||||
await self.flush_audio()
|
await self.flush_audio()
|
||||||
elif isinstance(frame, TTSUpdateSettingsFrame):
|
elif isinstance(frame, ServiceUpdateSettingsFrame) and frame.service_type == "tts":
|
||||||
await self._update_tts_settings(frame)
|
await self._update_settings(frame.settings)
|
||||||
else:
|
else:
|
||||||
await self.push_frame(frame, direction)
|
await self.push_frame(frame, direction)
|
||||||
|
|
||||||
@@ -341,34 +357,6 @@ class TTSService(AIService):
|
|||||||
# interrupted, the text is not added to the assistant context.
|
# interrupted, the text is not added to the assistant context.
|
||||||
await self.push_frame(TextFrame(text))
|
await self.push_frame(TextFrame(text))
|
||||||
|
|
||||||
async def _update_tts_settings(self, frame: TTSUpdateSettingsFrame):
|
|
||||||
if frame.model is not None:
|
|
||||||
await self.set_model(frame.model)
|
|
||||||
if frame.voice is not None:
|
|
||||||
await self.set_voice(frame.voice)
|
|
||||||
if frame.language is not None:
|
|
||||||
await self.set_language(frame.language)
|
|
||||||
if frame.speed is not None:
|
|
||||||
await self.set_speed(frame.speed)
|
|
||||||
if frame.emotion is not None:
|
|
||||||
await self.set_emotion(frame.emotion)
|
|
||||||
if frame.engine is not None:
|
|
||||||
await self.set_engine(frame.engine)
|
|
||||||
if frame.pitch is not None:
|
|
||||||
await self.set_pitch(frame.pitch)
|
|
||||||
if frame.rate is not None:
|
|
||||||
await self.set_rate(frame.rate)
|
|
||||||
if frame.volume is not None:
|
|
||||||
await self.set_volume(frame.volume)
|
|
||||||
if frame.emphasis is not None:
|
|
||||||
await self.set_emphasis(frame.emphasis)
|
|
||||||
if frame.style is not None:
|
|
||||||
await self.set_style(frame.style)
|
|
||||||
if frame.style_degree is not None:
|
|
||||||
await self.set_style_degree(frame.style_degree)
|
|
||||||
if frame.role is not None:
|
|
||||||
await self.set_role(frame.role)
|
|
||||||
|
|
||||||
async def _stop_frame_handler(self):
|
async def _stop_frame_handler(self):
|
||||||
try:
|
try:
|
||||||
has_started = False
|
has_started = False
|
||||||
@@ -454,6 +442,7 @@ class STTService(AIService):
|
|||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
|
self._settings: Dict[str, Any] = {}
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def set_model(self, model: str):
|
async def set_model(self, model: str):
|
||||||
@@ -468,11 +457,21 @@ class STTService(AIService):
|
|||||||
"""Returns transcript as a string"""
|
"""Returns transcript as a string"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
async def _update_stt_settings(self, frame: STTUpdateSettingsFrame):
|
async def _update_settings(self, settings: Dict[str, Any]):
|
||||||
if frame.model is not None:
|
for key, value in settings.items():
|
||||||
await self.set_model(frame.model)
|
setter = getattr(self, f"set_{key}", None)
|
||||||
if frame.language is not None:
|
if setter and callable(setter):
|
||||||
await self.set_language(frame.language)
|
try:
|
||||||
|
if key == "language":
|
||||||
|
await setter(Language(value))
|
||||||
|
else:
|
||||||
|
await setter(value)
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"Error setting {key}: {e}")
|
||||||
|
else:
|
||||||
|
logger.warning(f"Unknown setting for STT service: {key}")
|
||||||
|
|
||||||
|
self._settings.update(settings)
|
||||||
|
|
||||||
async def process_audio_frame(self, frame: AudioRawFrame):
|
async def process_audio_frame(self, frame: AudioRawFrame):
|
||||||
await self.process_generator(self.run_stt(frame.audio))
|
await self.process_generator(self.run_stt(frame.audio))
|
||||||
@@ -485,8 +484,8 @@ class STTService(AIService):
|
|||||||
# In this service we accumulate audio internally and at the end we
|
# In this service we accumulate audio internally and at the end we
|
||||||
# push a TextFrame. We don't really want to push audio frames down.
|
# push a TextFrame. We don't really want to push audio frames down.
|
||||||
await self.process_audio_frame(frame)
|
await self.process_audio_frame(frame)
|
||||||
elif isinstance(frame, STTUpdateSettingsFrame):
|
elif isinstance(frame, ServiceUpdateSettingsFrame) and frame.service_type == "stt":
|
||||||
await self._update_stt_settings(frame)
|
await self._update_settings(frame.settings)
|
||||||
else:
|
else:
|
||||||
await self.push_frame(frame, direction)
|
await self.push_frame(frame, direction)
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ from pipecat.frames.frames import (
|
|||||||
LLMFullResponseEndFrame,
|
LLMFullResponseEndFrame,
|
||||||
LLMFullResponseStartFrame,
|
LLMFullResponseStartFrame,
|
||||||
LLMMessagesFrame,
|
LLMMessagesFrame,
|
||||||
LLMUpdateSettingsFrame,
|
ServiceUpdateSettingsFrame,
|
||||||
StartInterruptionFrame,
|
StartInterruptionFrame,
|
||||||
TextFrame,
|
TextFrame,
|
||||||
UserImageRawFrame,
|
UserImageRawFrame,
|
||||||
@@ -284,20 +284,16 @@ class AnthropicLLMService(LLMService):
|
|||||||
cache_read_input_tokens=cache_read_input_tokens,
|
cache_read_input_tokens=cache_read_input_tokens,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def _update_settings(self, frame: LLMUpdateSettingsFrame):
|
async def _update_settings(self, settings: Dict[str, Any]):
|
||||||
if frame.model is not None:
|
for key, value in settings.items():
|
||||||
logger.debug(f"Switching LLM model to: [{frame.model}]")
|
setter = getattr(self, f"set_{key}", None)
|
||||||
self.set_model_name(frame.model)
|
if setter and callable(setter):
|
||||||
if frame.max_tokens is not None:
|
try:
|
||||||
await self.set_max_tokens(frame.max_tokens)
|
await setter(value)
|
||||||
if frame.temperature is not None:
|
except Exception as e:
|
||||||
await self.set_temperature(frame.temperature)
|
logger.warning(f"Error setting {key}: {e}")
|
||||||
if frame.top_k is not None:
|
else:
|
||||||
await self.set_top_k(frame.top_k)
|
logger.warning(f"Unknown setting for Anthropic LLM service: {key}")
|
||||||
if frame.top_p is not None:
|
|
||||||
await self.set_top_p(frame.top_p)
|
|
||||||
if frame.extra:
|
|
||||||
await self.set_extra(frame.extra)
|
|
||||||
|
|
||||||
async def process_frame(self, frame: Frame, direction: FrameDirection):
|
async def process_frame(self, frame: Frame, direction: FrameDirection):
|
||||||
await super().process_frame(frame, direction)
|
await super().process_frame(frame, direction)
|
||||||
@@ -313,8 +309,8 @@ class AnthropicLLMService(LLMService):
|
|||||||
# UserImageRawFrames coming through the pipeline and add them
|
# UserImageRawFrames coming through the pipeline and add them
|
||||||
# to the context.
|
# to the context.
|
||||||
context = AnthropicLLMContext.from_image_frame(frame)
|
context = AnthropicLLMContext.from_image_frame(frame)
|
||||||
elif isinstance(frame, LLMUpdateSettingsFrame):
|
elif isinstance(frame, ServiceUpdateSettingsFrame) and frame.service_type == "llm":
|
||||||
await self._update_settings(frame)
|
await self._update_settings(frame.settings)
|
||||||
elif isinstance(frame, LLMEnablePromptCachingFrame):
|
elif isinstance(frame, LLMEnablePromptCachingFrame):
|
||||||
logger.debug(f"Setting enable prompt caching to: [{frame.enable}]")
|
logger.debug(f"Setting enable prompt caching to: [{frame.enable}]")
|
||||||
self._enable_prompt_caching_beta = frame.enable
|
self._enable_prompt_caching_beta = frame.enable
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import json
|
import json
|
||||||
from typing import AsyncGenerator, List, Literal, Optional
|
from typing import Any, AsyncGenerator, Dict, List, Literal, Optional
|
||||||
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
@@ -17,7 +17,7 @@ from pipecat.frames.frames import (
|
|||||||
LLMFullResponseEndFrame,
|
LLMFullResponseEndFrame,
|
||||||
LLMFullResponseStartFrame,
|
LLMFullResponseStartFrame,
|
||||||
LLMMessagesFrame,
|
LLMMessagesFrame,
|
||||||
LLMUpdateSettingsFrame,
|
ServiceUpdateSettingsFrame,
|
||||||
TextFrame,
|
TextFrame,
|
||||||
TTSAudioRawFrame,
|
TTSAudioRawFrame,
|
||||||
TTSStartedFrame,
|
TTSStartedFrame,
|
||||||
@@ -64,6 +64,21 @@ class GoogleLLMService(LLMService):
|
|||||||
self.set_model_name(model)
|
self.set_model_name(model)
|
||||||
self._client = gai.GenerativeModel(model)
|
self._client = gai.GenerativeModel(model)
|
||||||
|
|
||||||
|
async def set_model(self, model: str):
|
||||||
|
logger.debug(f"Switching LLM model to: [{model}]")
|
||||||
|
self._create_client(model)
|
||||||
|
|
||||||
|
async def _update_settings(self, settings: Dict[str, Any]):
|
||||||
|
for key, value in settings.items():
|
||||||
|
setter = getattr(self, f"set_{key}", None)
|
||||||
|
if setter and callable(setter):
|
||||||
|
try:
|
||||||
|
await setter(value)
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"Error setting {key}: {e}")
|
||||||
|
else:
|
||||||
|
logger.warning(f"Unknown setting for Google LLM service: {key}")
|
||||||
|
|
||||||
def _get_messages_from_openai_context(self, context: OpenAILLMContext) -> List[glm.Content]:
|
def _get_messages_from_openai_context(self, context: OpenAILLMContext) -> List[glm.Content]:
|
||||||
openai_messages = context.get_messages()
|
openai_messages = context.get_messages()
|
||||||
google_messages = []
|
google_messages = []
|
||||||
@@ -136,10 +151,8 @@ class GoogleLLMService(LLMService):
|
|||||||
context = OpenAILLMContext.from_messages(frame.messages)
|
context = OpenAILLMContext.from_messages(frame.messages)
|
||||||
elif isinstance(frame, VisionImageRawFrame):
|
elif isinstance(frame, VisionImageRawFrame):
|
||||||
context = OpenAILLMContext.from_image_frame(frame)
|
context = OpenAILLMContext.from_image_frame(frame)
|
||||||
elif isinstance(frame, LLMUpdateSettingsFrame):
|
elif isinstance(frame, ServiceUpdateSettingsFrame) and frame.service_type == "llm":
|
||||||
if frame.model is not None:
|
await self._update_settings(frame.settings)
|
||||||
logger.debug(f"Switching LLM model to: [{frame.model}]")
|
|
||||||
self.set_model_name(frame.model)
|
|
||||||
else:
|
else:
|
||||||
await self.push_frame(frame, direction)
|
await self.push_frame(frame, direction)
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ from pipecat.frames.frames import (
|
|||||||
LLMFullResponseEndFrame,
|
LLMFullResponseEndFrame,
|
||||||
LLMFullResponseStartFrame,
|
LLMFullResponseStartFrame,
|
||||||
LLMMessagesFrame,
|
LLMMessagesFrame,
|
||||||
LLMUpdateSettingsFrame,
|
ServiceUpdateSettingsFrame,
|
||||||
StartInterruptionFrame,
|
StartInterruptionFrame,
|
||||||
TextFrame,
|
TextFrame,
|
||||||
TTSAudioRawFrame,
|
TTSAudioRawFrame,
|
||||||
@@ -295,22 +295,16 @@ class BaseOpenAILLMService(LLMService):
|
|||||||
f"The LLM tried to call a function named '{function_name}', but there isn't a callback registered for that function."
|
f"The LLM tried to call a function named '{function_name}', but there isn't a callback registered for that function."
|
||||||
)
|
)
|
||||||
|
|
||||||
async def _update_settings(self, frame: LLMUpdateSettingsFrame):
|
async def _update_settings(self, settings: Dict[str, Any]):
|
||||||
if frame.model is not None:
|
for key, value in settings.items():
|
||||||
logger.debug(f"Switching LLM model to: [{frame.model}]")
|
setter = getattr(self, f"set_{key}", None)
|
||||||
self.set_model_name(frame.model)
|
if setter and callable(setter):
|
||||||
if frame.frequency_penalty is not None:
|
try:
|
||||||
await self.set_frequency_penalty(frame.frequency_penalty)
|
await setter(value)
|
||||||
if frame.presence_penalty is not None:
|
except Exception as e:
|
||||||
await self.set_presence_penalty(frame.presence_penalty)
|
logger.warning(f"Error setting {key}: {e}")
|
||||||
if frame.seed is not None:
|
else:
|
||||||
await self.set_seed(frame.seed)
|
logger.warning(f"Unknown setting for OpenAI LLM service: {key}")
|
||||||
if frame.temperature is not None:
|
|
||||||
await self.set_temperature(frame.temperature)
|
|
||||||
if frame.top_p is not None:
|
|
||||||
await self.set_top_p(frame.top_p)
|
|
||||||
if frame.extra:
|
|
||||||
await self.set_extra(frame.extra)
|
|
||||||
|
|
||||||
async def process_frame(self, frame: Frame, direction: FrameDirection):
|
async def process_frame(self, frame: Frame, direction: FrameDirection):
|
||||||
await super().process_frame(frame, direction)
|
await super().process_frame(frame, direction)
|
||||||
@@ -322,8 +316,8 @@ class BaseOpenAILLMService(LLMService):
|
|||||||
context = OpenAILLMContext.from_messages(frame.messages)
|
context = OpenAILLMContext.from_messages(frame.messages)
|
||||||
elif isinstance(frame, VisionImageRawFrame):
|
elif isinstance(frame, VisionImageRawFrame):
|
||||||
context = OpenAILLMContext.from_image_frame(frame)
|
context = OpenAILLMContext.from_image_frame(frame)
|
||||||
elif isinstance(frame, LLMUpdateSettingsFrame):
|
elif isinstance(frame, ServiceUpdateSettingsFrame) and frame.service_type == "llm":
|
||||||
await self._update_settings(frame)
|
await self._update_settings(frame.settings)
|
||||||
else:
|
else:
|
||||||
await self.push_frame(frame, direction)
|
await self.push_frame(frame, direction)
|
||||||
|
|
||||||
|
|||||||
@@ -5,16 +5,13 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
from typing import Any, Dict, Optional
|
from typing import Any, Dict, Optional
|
||||||
|
|
||||||
import httpx
|
import httpx
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
from pydantic import BaseModel, Field
|
from pydantic import BaseModel, Field
|
||||||
|
|
||||||
from pipecat.frames.frames import (
|
|
||||||
LLMUpdateSettingsFrame,
|
|
||||||
)
|
|
||||||
from pipecat.services.openai import OpenAILLMService
|
from pipecat.services.openai import OpenAILLMService
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Together.ai is recommending OpenAI-compatible function calling, so we've switched over
|
# Together.ai is recommending OpenAI-compatible function calling, so we've switched over
|
||||||
# to using the OpenAI client library here rather than the Together Python client library.
|
# to using the OpenAI client library here rather than the Together Python client library.
|
||||||
@@ -104,21 +101,13 @@ class TogetherLLMService(OpenAILLMService):
|
|||||||
logger.debug(f"Switching LLM extra to: [{extra}]")
|
logger.debug(f"Switching LLM extra to: [{extra}]")
|
||||||
self._extra = extra
|
self._extra = extra
|
||||||
|
|
||||||
async def _update_settings(self, frame: LLMUpdateSettingsFrame):
|
async def _update_settings(self, settings: Dict[str, Any]):
|
||||||
if frame.model is not None:
|
for key, value in settings.items():
|
||||||
logger.debug(f"Switching LLM model to: [{frame.model}]")
|
setter = getattr(self, f"set_{key}", None)
|
||||||
self.set_model_name(frame.model)
|
if setter and callable(setter):
|
||||||
if frame.frequency_penalty is not None:
|
try:
|
||||||
await self.set_frequency_penalty(frame.frequency_penalty)
|
await setter(value)
|
||||||
if frame.max_tokens is not None:
|
except Exception as e:
|
||||||
await self.set_max_tokens(frame.max_tokens)
|
logger.warning(f"Error setting {key}: {e}")
|
||||||
if frame.presence_penalty is not None:
|
else:
|
||||||
await self.set_presence_penalty(frame.presence_penalty)
|
logger.warning(f"Unknown setting for Together LLM service: {key}")
|
||||||
if frame.temperature is not None:
|
|
||||||
await self.set_temperature(frame.temperature)
|
|
||||||
if frame.top_k is not None:
|
|
||||||
await self.set_top_k(frame.top_k)
|
|
||||||
if frame.top_p is not None:
|
|
||||||
await self.set_top_p(frame.top_p)
|
|
||||||
if frame.extra:
|
|
||||||
await self.set_extra(frame.extra)
|
|
||||||
|
|||||||
Reference in New Issue
Block a user