From 98bd530574abe8e9b456a24fcb1b38ddbdd84ce7 Mon Sep 17 00:00:00 2001 From: Mark Backman Date: Sat, 28 Feb 2026 14:05:25 -0500 Subject: [PATCH] Add changelog for #3881 --- changelog/3881.added.md | 2 +- .../utils/tracing/service_attributes.py | 14 ++++++-------- .../utils/tracing/service_decorators.py | 19 ++++++++++++------- 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/changelog/3881.added.md b/changelog/3881.added.md index cbf6d0293..c71475675 100644 --- a/changelog/3881.added.md +++ b/changelog/3881.added.md @@ -1 +1 @@ -- Added `StartupTimingObserver` for measuring how long each processor's `start()` method takes during pipeline startup. Also measures transport readiness — the time from `StartFrame` to first client connection — via the `on_transport_readiness_measured` event. Useful for diagnosing cold start slowness and identifying initialization bottlenecks. +- Added `StartupTimingObserver` for measuring how long each processor's `start()` method takes during pipeline startup. Also measures transport readiness — the time from `StartFrame` to first client connection — via the `on_transport_timing_report` event. diff --git a/src/pipecat/utils/tracing/service_attributes.py b/src/pipecat/utils/tracing/service_attributes.py index 97ac49d87..c8471a03b 100644 --- a/src/pipecat/utils/tracing/service_attributes.py +++ b/src/pipecat/utils/tracing/service_attributes.py @@ -17,8 +17,6 @@ from typing import TYPE_CHECKING, Any, Dict, List, Optional if TYPE_CHECKING: from opentelemetry.trace import Span - from pipecat.services.settings import ServiceSettings - from pipecat.utils.tracing.setup import is_tracing_available if is_tracing_available(): @@ -70,7 +68,7 @@ def add_tts_span_attributes( model: str, voice_id: str, text: Optional[str] = None, - settings: Optional["ServiceSettings"] = None, + settings: Optional[Dict[str, Any]] = None, character_count: Optional[int] = None, operation_name: str = "tts", ttfb: Optional[float] = None, @@ -109,7 +107,7 @@ def add_tts_span_attributes( # Add settings if provided if settings: - for key, value in settings.given_fields().items(): + for key, value in settings.items(): if isinstance(value, (str, int, float, bool)): span.set_attribute(f"settings.{key}", value) @@ -128,7 +126,7 @@ def add_stt_span_attributes( is_final: Optional[bool] = None, language: Optional[str] = None, user_id: Optional[str] = None, - settings: Optional["ServiceSettings"] = None, + settings: Optional[Dict[str, Any]] = None, vad_enabled: bool = False, ttfb: Optional[float] = None, **kwargs, @@ -173,7 +171,7 @@ def add_stt_span_attributes( # Add settings if provided if settings: - for key, value in settings.given_fields().items(): + for key, value in settings.items(): if isinstance(value, (str, int, float, bool)): span.set_attribute(f"settings.{key}", value) @@ -284,7 +282,7 @@ def add_gemini_live_span_attributes( voice_id: Optional[str] = None, language: Optional[str] = None, modalities: Optional[str] = None, - settings: Optional["ServiceSettings"] = None, + settings: Optional[Dict[str, Any]] = None, tools: Optional[List[Dict]] = None, tools_serialized: Optional[str] = None, transcript: Optional[str] = None, @@ -361,7 +359,7 @@ def add_gemini_live_span_attributes( # Add settings if provided if settings: - for key, value in settings.given_fields().items(): + for key, value in settings.items(): if isinstance(value, (str, int, float, bool)): span.set_attribute(f"settings.{key}", value) elif key == "vad" and value: diff --git a/src/pipecat/utils/tracing/service_decorators.py b/src/pipecat/utils/tracing/service_decorators.py index 304ecb5e8..601cad53d 100644 --- a/src/pipecat/utils/tracing/service_decorators.py +++ b/src/pipecat/utils/tracing/service_decorators.py @@ -219,7 +219,7 @@ def traced_tts(func: Optional[Callable] = None, *, name: Optional[str] = None) - tracer = trace.get_tracer("pipecat") with tracer.start_as_current_span(span_name, context=parent_context) as span: try: - settings = getattr(self, "_settings", None) + settings = getattr(self, "_settings", {}) add_tts_span_attributes( span=span, service_name=service_class_name, @@ -338,7 +338,7 @@ def traced_stt(func: Optional[Callable] = None, *, name: Optional[str] = None) - ) # Use settings from the service if available - settings = getattr(self, "_settings", None) + settings = getattr(self, "_settings", {}) add_stt_span_attributes( span=current_span, @@ -510,10 +510,15 @@ def traced_llm(func: Optional[Callable] = None, *, name: Optional[str] = None) - # Get settings from the service params = {} if hasattr(self, "_settings"): - for key, value in self._settings.given_fields().items(): + for key, value in self._settings.items(): + if key == "extra": + continue + # Add value directly if it's a basic type if isinstance(value, (int, float, bool, str)): params[key] = value - elif value is None: + elif value is None or ( + hasattr(value, "__name__") and value.__name__ == "NOT_GIVEN" + ): params[key] = "NOT_GIVEN" # Add all available attributes to the span @@ -622,12 +627,12 @@ def traced_gemini_live(operation: str) -> Callable: model_name = _get_model_name(self) voice_id = getattr(self, "_voice_id", None) language_code = getattr(self, "_language_code", None) - settings = getattr(self, "_settings", None) + settings = getattr(self, "_settings", {}) # Get modalities if available modalities = None - if settings and hasattr(settings, "modalities"): - modality_obj = settings.modalities + if hasattr(self, "_settings") and "modalities" in self._settings: + modality_obj = self._settings["modalities"] if hasattr(modality_obj, "value"): modalities = modality_obj.value else: