Merge pull request #2517 from pipecat-ai/aleix/unify-get-messages-for-logging

unify get_messages_for_logging()
This commit is contained in:
Aleix Conchillo Flaqué
2025-08-27 12:49:36 -07:00
committed by GitHub
13 changed files with 33 additions and 30 deletions

View File

@@ -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`.

View File

@@ -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:

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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")

View File

@@ -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.

View File

@@ -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).

View File

@@ -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):

View File

@@ -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):

View File

@@ -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)

View File

@@ -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)