diff --git a/CHANGELOG.md b/CHANGELOG.md index 84ab4770c..c7734e4d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -100,6 +100,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- Fixed some `get_messages_for_logging()` that were returning a JSON string + instead of a list. + - Fixed a `DailyTransport` issue that prevented DTMF tones from being sent. - Fixed a missing import in `SentryMetrics`. diff --git a/src/pipecat/adapters/base_llm_adapter.py b/src/pipecat/adapters/base_llm_adapter.py index d24dd4b26..2996c811c 100644 --- a/src/pipecat/adapters/base_llm_adapter.py +++ b/src/pipecat/adapters/base_llm_adapter.py @@ -11,7 +11,7 @@ adapters that handle tool format conversion and standardization. """ from abc import ABC, abstractmethod -from typing import Any, Generic, List, TypeVar, Union, cast +from typing import Any, Dict, Generic, List, TypeVar from loguru import logger @@ -63,7 +63,7 @@ class BaseLLMAdapter(ABC, Generic[TLLMInvocationParams]): pass @abstractmethod - def get_messages_for_logging(self, context: LLMContext) -> List[dict[str, Any]]: + def get_messages_for_logging(self, context: LLMContext) -> List[Dict[str, Any]]: """Get messages from a universal LLM context in a format ready for logging about this provider. Args: diff --git a/src/pipecat/adapters/services/anthropic_adapter.py b/src/pipecat/adapters/services/anthropic_adapter.py index 4ba73956b..45c8bced2 100644 --- a/src/pipecat/adapters/services/anthropic_adapter.py +++ b/src/pipecat/adapters/services/anthropic_adapter.py @@ -43,7 +43,7 @@ class AnthropicLLMAdapter(BaseLLMAdapter[AnthropicLLMInvocationParams]): """ raise NotImplementedError("Universal LLMContext is not yet supported for Anthropic.") - def get_messages_for_logging(self, context) -> List[dict[str, Any]]: + def get_messages_for_logging(self, context) -> List[Dict[str, Any]]: """Get messages from a universal LLM context in a format ready for logging about Anthropic. Removes or truncates sensitive data like image content for safe logging. diff --git a/src/pipecat/adapters/services/aws_nova_sonic_adapter.py b/src/pipecat/adapters/services/aws_nova_sonic_adapter.py index 2627052eb..8da38e23b 100644 --- a/src/pipecat/adapters/services/aws_nova_sonic_adapter.py +++ b/src/pipecat/adapters/services/aws_nova_sonic_adapter.py @@ -44,7 +44,7 @@ class AWSNovaSonicLLMAdapter(BaseLLMAdapter[AWSNovaSonicLLMInvocationParams]): """ raise NotImplementedError("Universal LLMContext is not yet supported for AWS Nova Sonic.") - def get_messages_for_logging(self, context) -> List[dict[str, Any]]: + def get_messages_for_logging(self, context) -> List[Dict[str, Any]]: """Get messages from a universal LLM context in a format ready for logging about AWS Nova Sonic. Removes or truncates sensitive data like image content for safe logging. diff --git a/src/pipecat/adapters/services/bedrock_adapter.py b/src/pipecat/adapters/services/bedrock_adapter.py index 5f556ec9b..0be2527b1 100644 --- a/src/pipecat/adapters/services/bedrock_adapter.py +++ b/src/pipecat/adapters/services/bedrock_adapter.py @@ -43,7 +43,7 @@ class AWSBedrockLLMAdapter(BaseLLMAdapter[AWSBedrockLLMInvocationParams]): """ raise NotImplementedError("Universal LLMContext is not yet supported for AWS Bedrock.") - def get_messages_for_logging(self, context) -> List[dict[str, Any]]: + def get_messages_for_logging(self, context) -> List[Dict[str, Any]]: """Get messages from a universal LLM context in a format ready for logging about AWS Bedrock. Removes or truncates sensitive data like image content for safe logging. diff --git a/src/pipecat/adapters/services/gemini_adapter.py b/src/pipecat/adapters/services/gemini_adapter.py index 31345821f..ca17791a3 100644 --- a/src/pipecat/adapters/services/gemini_adapter.py +++ b/src/pipecat/adapters/services/gemini_adapter.py @@ -91,7 +91,7 @@ class GeminiLLMAdapter(BaseLLMAdapter[GeminiLLMInvocationParams]): return formatted_standard_tools + custom_gemini_tools - def get_messages_for_logging(self, context: LLMContext) -> List[dict[str, Any]]: + def get_messages_for_logging(self, context: LLMContext) -> List[Dict[str, Any]]: """Get messages from a universal LLM context in a format ready for logging about Gemini. Removes or truncates sensitive data like image content for safe logging. diff --git a/src/pipecat/adapters/services/open_ai_adapter.py b/src/pipecat/adapters/services/open_ai_adapter.py index 2ba5b0319..7e70da781 100644 --- a/src/pipecat/adapters/services/open_ai_adapter.py +++ b/src/pipecat/adapters/services/open_ai_adapter.py @@ -8,7 +8,7 @@ import copy import json -from typing import Any, List, TypedDict +from typing import Any, Dict, List, TypedDict from openai._types import NOT_GIVEN as OPEN_AI_NOT_GIVEN from openai._types import NotGiven as OpenAINotGiven @@ -79,7 +79,7 @@ class OpenAILLMAdapter(BaseLLMAdapter[OpenAILLMInvocationParams]): for func in functions_schema ] - def get_messages_for_logging(self, context: LLMContext) -> List[dict[str, Any]]: + def get_messages_for_logging(self, context: LLMContext) -> List[Dict[str, Any]]: """Get messages from a universal LLM context in a format ready for logging about OpenAI. Removes or truncates sensitive data like image content for safe logging. @@ -102,7 +102,7 @@ class OpenAILLMAdapter(BaseLLMAdapter[OpenAILLMInvocationParams]): if "mime_type" in msg and msg["mime_type"].startswith("image/"): msg["data"] = "..." msgs.append(msg) - return json.dumps(msgs, ensure_ascii=False) + return msgs def _get_messages(self, context: LLMContext) -> List[LLMContextMessage]: return context.get_messages("openai") diff --git a/src/pipecat/adapters/services/open_ai_realtime_adapter.py b/src/pipecat/adapters/services/open_ai_realtime_adapter.py index 705df525e..d2fd831ba 100644 --- a/src/pipecat/adapters/services/open_ai_realtime_adapter.py +++ b/src/pipecat/adapters/services/open_ai_realtime_adapter.py @@ -6,7 +6,7 @@ """OpenAI Realtime LLM adapter for Pipecat.""" -from typing import Any, Dict, List, TypedDict, Union +from typing import Any, Dict, List, TypedDict from pipecat.adapters.base_llm_adapter import BaseLLMAdapter from pipecat.adapters.schemas.function_schema import FunctionSchema @@ -43,7 +43,7 @@ class OpenAIRealtimeLLMAdapter(BaseLLMAdapter): """ raise NotImplementedError("Universal LLMContext is not yet supported for OpenAI Realtime.") - def get_messages_for_logging(self, context) -> List[dict[str, Any]]: + def get_messages_for_logging(self, context) -> List[Dict[str, Any]]: """Get messages from a universal LLM context in a format ready for logging about OpenAI Realtime. Removes or truncates sensitive data like image content for safe logging. diff --git a/src/pipecat/processors/aggregators/openai_llm_context.py b/src/pipecat/processors/aggregators/openai_llm_context.py index c00b9fbe7..22daacf8a 100644 --- a/src/pipecat/processors/aggregators/openai_llm_context.py +++ b/src/pipecat/processors/aggregators/openai_llm_context.py @@ -15,7 +15,7 @@ import copy import io import json from dataclasses import dataclass -from typing import Any, List, Optional +from typing import Any, Dict, List, Optional from openai._types import NOT_GIVEN, NotGiven from openai.types.chat import ( @@ -183,13 +183,13 @@ class OpenAILLMContext: """ return json.dumps(self._messages, cls=CustomEncoder, ensure_ascii=False, indent=2) - def get_messages_for_logging(self) -> str: + def get_messages_for_logging(self) -> List[Dict[str, Any]]: """Get sanitized messages suitable for logging. Removes or truncates sensitive data like image content for safe logging. Returns: - JSON string with sanitized message content for logging. + List of messages in a format ready for logging. """ msgs = [] for message in self.messages: @@ -203,7 +203,7 @@ class OpenAILLMContext: if "mime_type" in msg and msg["mime_type"].startswith("image/"): msg["data"] = "..." msgs.append(msg) - return json.dumps(msgs, ensure_ascii=False) + return msgs def from_standard_message(self, message): """Convert from OpenAI message format to OpenAI message format (passthrough). diff --git a/src/pipecat/services/anthropic/llm.py b/src/pipecat/services/anthropic/llm.py index ee042aa1b..dcf21cf12 100644 --- a/src/pipecat/services/anthropic/llm.py +++ b/src/pipecat/services/anthropic/llm.py @@ -295,7 +295,7 @@ class AnthropicLLMService(LLMService): await self.start_processing_metrics() logger.debug( - f"{self}: Generating chat [{context.system}] | [{context.get_messages_for_logging()}]" + f"{self}: Generating chat [{context.system}] | {context.get_messages_for_logging()}" ) messages = context.messages @@ -933,13 +933,13 @@ class AnthropicLLMContext(OpenAILLMContext): messages.insert(0, {"role": "system", "content": self.system}) return messages - def get_messages_for_logging(self) -> str: + def get_messages_for_logging(self) -> List[Dict[str, Any]]: """Get messages formatted for logging with sensitive data redacted. Replaces image data with placeholder text for cleaner logs. Returns: - JSON string representation of messages for logging. + List of messages in a format ready for logging. """ msgs = [] for message in self.messages: @@ -950,7 +950,7 @@ class AnthropicLLMContext(OpenAILLMContext): if item["type"] == "image": item["source"]["data"] = "..." msgs.append(msg) - return json.dumps(msgs) + return msgs class AnthropicUserContextAggregator(LLMUserContextAggregator): diff --git a/src/pipecat/services/aws/llm.py b/src/pipecat/services/aws/llm.py index 7b9691b04..307db7b22 100644 --- a/src/pipecat/services/aws/llm.py +++ b/src/pipecat/services/aws/llm.py @@ -556,11 +556,11 @@ class AWSBedrockLLMContext(OpenAILLMContext): messages.insert(0, {"role": "system", "content": self.system}) return messages - def get_messages_for_logging(self) -> str: + def get_messages_for_logging(self) -> List[Dict[str, Any]]: """Get messages formatted for logging with sensitive data redacted. Returns: - JSON string representation of messages with image data redacted. + List of messages in a format ready for logging. """ msgs = [] for message in self.messages: @@ -571,7 +571,7 @@ class AWSBedrockLLMContext(OpenAILLMContext): if item.get("image"): item["source"]["bytes"] = "..." msgs.append(msg) - return json.dumps(msgs) + return msgs class AWSBedrockUserContextAggregator(LLMUserContextAggregator): diff --git a/src/pipecat/services/google/llm.py b/src/pipecat/services/google/llm.py index 7a140c363..dd4dce18c 100644 --- a/src/pipecat/services/google/llm.py +++ b/src/pipecat/services/google/llm.py @@ -292,11 +292,11 @@ class GoogleLLMContext(OpenAILLMContext): # Add the converted messages to our existing messages self._messages.extend(converted_messages) - def get_messages_for_logging(self): + def get_messages_for_logging(self) -> List[Dict[str, Any]]: """Get messages formatted for logging with sensitive data redacted. Returns: - List of message dictionaries with inline data redacted. + List of messages in a format ready for logging. """ msgs = [] for message in self.messages: @@ -858,8 +858,8 @@ class GoogleLLMService(LLMService): self, context: OpenAILLMContext ) -> AsyncIterator[GenerateContentResponse]: logger.debug( - # f"{self}: Generating chat [{self._system_instruction}] | [{context.get_messages_for_logging()}]" - f"{self}: Generating chat from OpenAI context [{context.get_messages_for_logging()}]" + # f"{self}: Generating chat [{self._system_instruction}] | {context.get_messages_for_logging()}" + f"{self}: Generating chat from OpenAI context {context.get_messages_for_logging()}" ) params = GeminiLLMInvocationParams( @@ -875,8 +875,8 @@ class GoogleLLMService(LLMService): ) -> AsyncIterator[GenerateContentResponse]: adapter = self.get_llm_adapter() logger.debug( - # f"{self}: Generating chat [{self._system_instruction}] | [{context.get_messages_for_logging()}]" - f"{self}: Generating chat from universal context [{adapter.get_messages_for_logging(context)}]" + # f"{self}: Generating chat [{self._system_instruction}] | {context.get_messages_for_logging()}" + f"{self}: Generating chat from universal context {adapter.get_messages_for_logging(context)}" ) params: GeminiLLMInvocationParams = adapter.get_llm_invocation_params(context) diff --git a/src/pipecat/services/openai/base_llm.py b/src/pipecat/services/openai/base_llm.py index e51755cba..42eeb8981 100644 --- a/src/pipecat/services/openai/base_llm.py +++ b/src/pipecat/services/openai/base_llm.py @@ -279,7 +279,7 @@ class BaseOpenAILLMService(LLMService): self, context: OpenAILLMContext ) -> AsyncStream[ChatCompletionChunk]: logger.debug( - f"{self}: Generating chat from OpenAI context [{context.get_messages_for_logging()}]" + f"{self}: Generating chat from OpenAI context {context.get_messages_for_logging()}" ) messages: List[ChatCompletionMessageParam] = context.get_messages() @@ -311,7 +311,7 @@ class BaseOpenAILLMService(LLMService): ) -> AsyncStream[ChatCompletionChunk]: adapter = self.get_llm_adapter() logger.debug( - f"{self}: Generating chat from universal context [{adapter.get_messages_for_logging(context)}]" + f"{self}: Generating chat from universal context {adapter.get_messages_for_logging(context)}" ) params: OpenAILLMInvocationParams = adapter.get_llm_invocation_params(context)