dv-pipecat-ai 0.0.74.dev770__py3-none-any.whl → 0.0.82.dev776__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of dv-pipecat-ai might be problematic. Click here for more details.

Files changed (244) hide show
  1. {dv_pipecat_ai-0.0.74.dev770.dist-info → dv_pipecat_ai-0.0.82.dev776.dist-info}/METADATA +137 -93
  2. dv_pipecat_ai-0.0.82.dev776.dist-info/RECORD +340 -0
  3. pipecat/__init__.py +17 -0
  4. pipecat/adapters/base_llm_adapter.py +36 -1
  5. pipecat/adapters/schemas/direct_function.py +296 -0
  6. pipecat/adapters/schemas/function_schema.py +15 -6
  7. pipecat/adapters/schemas/tools_schema.py +55 -7
  8. pipecat/adapters/services/anthropic_adapter.py +22 -3
  9. pipecat/adapters/services/aws_nova_sonic_adapter.py +23 -3
  10. pipecat/adapters/services/bedrock_adapter.py +22 -3
  11. pipecat/adapters/services/gemini_adapter.py +16 -3
  12. pipecat/adapters/services/open_ai_adapter.py +17 -2
  13. pipecat/adapters/services/open_ai_realtime_adapter.py +23 -3
  14. pipecat/audio/filters/base_audio_filter.py +30 -6
  15. pipecat/audio/filters/koala_filter.py +37 -2
  16. pipecat/audio/filters/krisp_filter.py +59 -6
  17. pipecat/audio/filters/noisereduce_filter.py +37 -0
  18. pipecat/audio/interruptions/base_interruption_strategy.py +25 -5
  19. pipecat/audio/interruptions/min_words_interruption_strategy.py +21 -4
  20. pipecat/audio/mixers/base_audio_mixer.py +30 -7
  21. pipecat/audio/mixers/soundfile_mixer.py +53 -6
  22. pipecat/audio/resamplers/base_audio_resampler.py +17 -9
  23. pipecat/audio/resamplers/resampy_resampler.py +26 -1
  24. pipecat/audio/resamplers/soxr_resampler.py +32 -1
  25. pipecat/audio/resamplers/soxr_stream_resampler.py +101 -0
  26. pipecat/audio/utils.py +194 -1
  27. pipecat/audio/vad/silero.py +60 -3
  28. pipecat/audio/vad/vad_analyzer.py +114 -30
  29. pipecat/clocks/base_clock.py +19 -0
  30. pipecat/clocks/system_clock.py +25 -0
  31. pipecat/extensions/voicemail/__init__.py +0 -0
  32. pipecat/extensions/voicemail/voicemail_detector.py +707 -0
  33. pipecat/frames/frames.py +590 -156
  34. pipecat/metrics/metrics.py +64 -1
  35. pipecat/observers/base_observer.py +58 -19
  36. pipecat/observers/loggers/debug_log_observer.py +56 -64
  37. pipecat/observers/loggers/llm_log_observer.py +8 -1
  38. pipecat/observers/loggers/transcription_log_observer.py +19 -7
  39. pipecat/observers/loggers/user_bot_latency_log_observer.py +32 -5
  40. pipecat/observers/turn_tracking_observer.py +26 -1
  41. pipecat/pipeline/base_pipeline.py +5 -7
  42. pipecat/pipeline/base_task.py +52 -9
  43. pipecat/pipeline/parallel_pipeline.py +121 -177
  44. pipecat/pipeline/pipeline.py +129 -20
  45. pipecat/pipeline/runner.py +50 -1
  46. pipecat/pipeline/sync_parallel_pipeline.py +132 -32
  47. pipecat/pipeline/task.py +263 -280
  48. pipecat/pipeline/task_observer.py +85 -34
  49. pipecat/pipeline/to_be_updated/merge_pipeline.py +32 -2
  50. pipecat/processors/aggregators/dtmf_aggregator.py +29 -22
  51. pipecat/processors/aggregators/gated.py +25 -24
  52. pipecat/processors/aggregators/gated_openai_llm_context.py +22 -2
  53. pipecat/processors/aggregators/llm_response.py +398 -89
  54. pipecat/processors/aggregators/openai_llm_context.py +161 -13
  55. pipecat/processors/aggregators/sentence.py +25 -14
  56. pipecat/processors/aggregators/user_response.py +28 -3
  57. pipecat/processors/aggregators/vision_image_frame.py +24 -14
  58. pipecat/processors/async_generator.py +28 -0
  59. pipecat/processors/audio/audio_buffer_processor.py +78 -37
  60. pipecat/processors/consumer_processor.py +25 -6
  61. pipecat/processors/filters/frame_filter.py +23 -0
  62. pipecat/processors/filters/function_filter.py +30 -0
  63. pipecat/processors/filters/identity_filter.py +17 -2
  64. pipecat/processors/filters/null_filter.py +24 -1
  65. pipecat/processors/filters/stt_mute_filter.py +56 -21
  66. pipecat/processors/filters/wake_check_filter.py +46 -3
  67. pipecat/processors/filters/wake_notifier_filter.py +21 -3
  68. pipecat/processors/frame_processor.py +488 -131
  69. pipecat/processors/frameworks/langchain.py +38 -3
  70. pipecat/processors/frameworks/rtvi.py +719 -34
  71. pipecat/processors/gstreamer/pipeline_source.py +41 -0
  72. pipecat/processors/idle_frame_processor.py +26 -3
  73. pipecat/processors/logger.py +23 -0
  74. pipecat/processors/metrics/frame_processor_metrics.py +77 -4
  75. pipecat/processors/metrics/sentry.py +42 -4
  76. pipecat/processors/producer_processor.py +34 -14
  77. pipecat/processors/text_transformer.py +22 -10
  78. pipecat/processors/transcript_processor.py +48 -29
  79. pipecat/processors/user_idle_processor.py +31 -21
  80. pipecat/runner/__init__.py +1 -0
  81. pipecat/runner/daily.py +132 -0
  82. pipecat/runner/livekit.py +148 -0
  83. pipecat/runner/run.py +543 -0
  84. pipecat/runner/types.py +67 -0
  85. pipecat/runner/utils.py +515 -0
  86. pipecat/serializers/base_serializer.py +42 -0
  87. pipecat/serializers/exotel.py +17 -6
  88. pipecat/serializers/genesys.py +95 -0
  89. pipecat/serializers/livekit.py +33 -0
  90. pipecat/serializers/plivo.py +16 -15
  91. pipecat/serializers/protobuf.py +37 -1
  92. pipecat/serializers/telnyx.py +18 -17
  93. pipecat/serializers/twilio.py +32 -16
  94. pipecat/services/ai_service.py +5 -3
  95. pipecat/services/anthropic/llm.py +113 -43
  96. pipecat/services/assemblyai/models.py +63 -5
  97. pipecat/services/assemblyai/stt.py +64 -11
  98. pipecat/services/asyncai/__init__.py +0 -0
  99. pipecat/services/asyncai/tts.py +501 -0
  100. pipecat/services/aws/llm.py +185 -111
  101. pipecat/services/aws/stt.py +217 -23
  102. pipecat/services/aws/tts.py +118 -52
  103. pipecat/services/aws/utils.py +101 -5
  104. pipecat/services/aws_nova_sonic/aws.py +82 -64
  105. pipecat/services/aws_nova_sonic/context.py +15 -6
  106. pipecat/services/azure/common.py +10 -2
  107. pipecat/services/azure/image.py +32 -0
  108. pipecat/services/azure/llm.py +9 -7
  109. pipecat/services/azure/stt.py +65 -2
  110. pipecat/services/azure/tts.py +154 -23
  111. pipecat/services/cartesia/stt.py +125 -8
  112. pipecat/services/cartesia/tts.py +102 -38
  113. pipecat/services/cerebras/llm.py +15 -23
  114. pipecat/services/deepgram/stt.py +19 -11
  115. pipecat/services/deepgram/tts.py +36 -0
  116. pipecat/services/deepseek/llm.py +14 -23
  117. pipecat/services/elevenlabs/tts.py +330 -64
  118. pipecat/services/fal/image.py +43 -0
  119. pipecat/services/fal/stt.py +48 -10
  120. pipecat/services/fireworks/llm.py +14 -21
  121. pipecat/services/fish/tts.py +109 -9
  122. pipecat/services/gemini_multimodal_live/__init__.py +1 -0
  123. pipecat/services/gemini_multimodal_live/events.py +83 -2
  124. pipecat/services/gemini_multimodal_live/file_api.py +189 -0
  125. pipecat/services/gemini_multimodal_live/gemini.py +218 -21
  126. pipecat/services/gladia/config.py +17 -10
  127. pipecat/services/gladia/stt.py +82 -36
  128. pipecat/services/google/frames.py +40 -0
  129. pipecat/services/google/google.py +2 -0
  130. pipecat/services/google/image.py +39 -2
  131. pipecat/services/google/llm.py +176 -58
  132. pipecat/services/google/llm_openai.py +26 -4
  133. pipecat/services/google/llm_vertex.py +37 -15
  134. pipecat/services/google/rtvi.py +41 -0
  135. pipecat/services/google/stt.py +65 -17
  136. pipecat/services/google/test-google-chirp.py +45 -0
  137. pipecat/services/google/tts.py +390 -19
  138. pipecat/services/grok/llm.py +8 -6
  139. pipecat/services/groq/llm.py +8 -6
  140. pipecat/services/groq/stt.py +13 -9
  141. pipecat/services/groq/tts.py +40 -0
  142. pipecat/services/hamsa/__init__.py +9 -0
  143. pipecat/services/hamsa/stt.py +241 -0
  144. pipecat/services/heygen/__init__.py +5 -0
  145. pipecat/services/heygen/api.py +281 -0
  146. pipecat/services/heygen/client.py +620 -0
  147. pipecat/services/heygen/video.py +338 -0
  148. pipecat/services/image_service.py +5 -3
  149. pipecat/services/inworld/__init__.py +1 -0
  150. pipecat/services/inworld/tts.py +592 -0
  151. pipecat/services/llm_service.py +127 -45
  152. pipecat/services/lmnt/tts.py +80 -7
  153. pipecat/services/mcp_service.py +85 -44
  154. pipecat/services/mem0/memory.py +42 -13
  155. pipecat/services/minimax/tts.py +74 -15
  156. pipecat/services/mistral/__init__.py +0 -0
  157. pipecat/services/mistral/llm.py +185 -0
  158. pipecat/services/moondream/vision.py +55 -10
  159. pipecat/services/neuphonic/tts.py +275 -48
  160. pipecat/services/nim/llm.py +8 -6
  161. pipecat/services/ollama/llm.py +27 -7
  162. pipecat/services/openai/base_llm.py +54 -16
  163. pipecat/services/openai/image.py +30 -0
  164. pipecat/services/openai/llm.py +7 -5
  165. pipecat/services/openai/stt.py +13 -9
  166. pipecat/services/openai/tts.py +42 -10
  167. pipecat/services/openai_realtime_beta/azure.py +11 -9
  168. pipecat/services/openai_realtime_beta/context.py +7 -5
  169. pipecat/services/openai_realtime_beta/events.py +10 -7
  170. pipecat/services/openai_realtime_beta/openai.py +37 -18
  171. pipecat/services/openpipe/llm.py +30 -24
  172. pipecat/services/openrouter/llm.py +9 -7
  173. pipecat/services/perplexity/llm.py +15 -19
  174. pipecat/services/piper/tts.py +26 -12
  175. pipecat/services/playht/tts.py +227 -65
  176. pipecat/services/qwen/llm.py +8 -6
  177. pipecat/services/rime/tts.py +128 -17
  178. pipecat/services/riva/stt.py +160 -22
  179. pipecat/services/riva/tts.py +67 -2
  180. pipecat/services/sambanova/llm.py +19 -17
  181. pipecat/services/sambanova/stt.py +14 -8
  182. pipecat/services/sarvam/tts.py +60 -13
  183. pipecat/services/simli/video.py +82 -21
  184. pipecat/services/soniox/__init__.py +0 -0
  185. pipecat/services/soniox/stt.py +398 -0
  186. pipecat/services/speechmatics/stt.py +29 -17
  187. pipecat/services/stt_service.py +47 -11
  188. pipecat/services/tavus/video.py +94 -25
  189. pipecat/services/together/llm.py +8 -6
  190. pipecat/services/tts_service.py +77 -53
  191. pipecat/services/ultravox/stt.py +46 -43
  192. pipecat/services/vision_service.py +5 -3
  193. pipecat/services/websocket_service.py +12 -11
  194. pipecat/services/whisper/base_stt.py +58 -12
  195. pipecat/services/whisper/stt.py +69 -58
  196. pipecat/services/xtts/tts.py +59 -2
  197. pipecat/sync/base_notifier.py +19 -0
  198. pipecat/sync/event_notifier.py +24 -0
  199. pipecat/tests/utils.py +73 -5
  200. pipecat/transcriptions/language.py +24 -0
  201. pipecat/transports/base_input.py +112 -8
  202. pipecat/transports/base_output.py +235 -13
  203. pipecat/transports/base_transport.py +119 -0
  204. pipecat/transports/local/audio.py +76 -0
  205. pipecat/transports/local/tk.py +84 -0
  206. pipecat/transports/network/fastapi_websocket.py +174 -15
  207. pipecat/transports/network/small_webrtc.py +383 -39
  208. pipecat/transports/network/webrtc_connection.py +214 -8
  209. pipecat/transports/network/websocket_client.py +171 -1
  210. pipecat/transports/network/websocket_server.py +147 -9
  211. pipecat/transports/services/daily.py +792 -70
  212. pipecat/transports/services/helpers/daily_rest.py +122 -129
  213. pipecat/transports/services/livekit.py +339 -4
  214. pipecat/transports/services/tavus.py +273 -38
  215. pipecat/utils/asyncio/task_manager.py +92 -186
  216. pipecat/utils/base_object.py +83 -1
  217. pipecat/utils/network.py +2 -0
  218. pipecat/utils/string.py +114 -58
  219. pipecat/utils/text/base_text_aggregator.py +44 -13
  220. pipecat/utils/text/base_text_filter.py +46 -0
  221. pipecat/utils/text/markdown_text_filter.py +70 -14
  222. pipecat/utils/text/pattern_pair_aggregator.py +18 -14
  223. pipecat/utils/text/simple_text_aggregator.py +43 -2
  224. pipecat/utils/text/skip_tags_aggregator.py +21 -13
  225. pipecat/utils/time.py +36 -0
  226. pipecat/utils/tracing/class_decorators.py +32 -7
  227. pipecat/utils/tracing/conversation_context_provider.py +12 -2
  228. pipecat/utils/tracing/service_attributes.py +80 -64
  229. pipecat/utils/tracing/service_decorators.py +48 -21
  230. pipecat/utils/tracing/setup.py +13 -7
  231. pipecat/utils/tracing/turn_context_provider.py +12 -2
  232. pipecat/utils/tracing/turn_trace_observer.py +27 -0
  233. pipecat/utils/utils.py +14 -14
  234. dv_pipecat_ai-0.0.74.dev770.dist-info/RECORD +0 -319
  235. pipecat/examples/daily_runner.py +0 -64
  236. pipecat/examples/run.py +0 -265
  237. pipecat/utils/asyncio/watchdog_async_iterator.py +0 -72
  238. pipecat/utils/asyncio/watchdog_event.py +0 -42
  239. pipecat/utils/asyncio/watchdog_priority_queue.py +0 -48
  240. pipecat/utils/asyncio/watchdog_queue.py +0 -48
  241. {dv_pipecat_ai-0.0.74.dev770.dist-info → dv_pipecat_ai-0.0.82.dev776.dist-info}/WHEEL +0 -0
  242. {dv_pipecat_ai-0.0.74.dev770.dist-info → dv_pipecat_ai-0.0.82.dev776.dist-info}/licenses/LICENSE +0 -0
  243. {dv_pipecat_ai-0.0.74.dev770.dist-info → dv_pipecat_ai-0.0.82.dev776.dist-info}/top_level.txt +0 -0
  244. /pipecat/{examples → extensions}/__init__.py +0 -0
@@ -1,39 +1,102 @@
1
+ #
2
+ # Copyright (c) 2024–2025, Daily
3
+ #
4
+ # SPDX-License-Identifier: BSD 2-Clause License
5
+ #
6
+
7
+ """Metrics data models for Pipecat framework.
8
+
9
+ This module defines Pydantic models for various types of metrics data
10
+ collected throughout the pipeline, including timing, token usage, and
11
+ processing statistics.
12
+ """
13
+
1
14
  from typing import Optional
2
15
 
3
16
  from pydantic import BaseModel
4
17
 
5
18
 
6
19
  class MetricsData(BaseModel):
20
+ """Base class for all metrics data.
21
+
22
+ Parameters:
23
+ processor: Name of the processor generating the metrics.
24
+ model: Optional model name associated with the metrics.
25
+ """
26
+
7
27
  processor: str
8
28
  model: Optional[str] = None
9
29
 
10
30
 
11
31
  class TTFBMetricsData(MetricsData):
32
+ """Time To First Byte (TTFB) metrics data.
33
+
34
+ Parameters:
35
+ value: TTFB measurement in seconds.
36
+ """
37
+
12
38
  value: float
13
39
 
14
40
 
15
41
  class ProcessingMetricsData(MetricsData):
42
+ """General processing time metrics data.
43
+
44
+ Parameters:
45
+ value: Processing time measurement in seconds.
46
+ """
47
+
16
48
  value: float
17
49
 
18
50
 
19
51
  class LLMTokenUsage(BaseModel):
52
+ """Token usage statistics for LLM operations.
53
+
54
+ Parameters:
55
+ prompt_tokens: Number of tokens in the input prompt.
56
+ completion_tokens: Number of tokens in the generated completion.
57
+ total_tokens: Total number of tokens used (prompt + completion).
58
+ cache_read_input_tokens: Number of tokens read from cache, if applicable.
59
+ cache_creation_input_tokens: Number of tokens used to create cache entries, if applicable.
60
+ """
61
+
20
62
  prompt_tokens: int
21
63
  completion_tokens: int
22
64
  total_tokens: int
23
65
  cache_read_input_tokens: Optional[int] = None
24
66
  cache_creation_input_tokens: Optional[int] = None
67
+ reasoning_tokens: Optional[int] = None
25
68
 
26
69
 
27
70
  class LLMUsageMetricsData(MetricsData):
71
+ """LLM token usage metrics data.
72
+
73
+ Parameters:
74
+ value: Token usage statistics for the LLM operation.
75
+ """
76
+
28
77
  value: LLMTokenUsage
29
78
 
30
79
 
31
80
  class TTSUsageMetricsData(MetricsData):
81
+ """Text-to-Speech usage metrics data.
82
+
83
+ Parameters:
84
+ value: Number of characters processed by TTS.
85
+ """
86
+
32
87
  value: int
33
88
 
34
89
 
35
90
  class SmartTurnMetricsData(MetricsData):
36
- """Metrics data for smart turn predictions."""
91
+ """Metrics data for smart turn predictions.
92
+
93
+ Parameters:
94
+ is_complete: Whether the turn is predicted to be complete.
95
+ probability: Confidence probability of the turn completion prediction.
96
+ inference_time_ms: Time taken for inference in milliseconds.
97
+ server_total_time_ms: Total server processing time in milliseconds.
98
+ e2e_processing_time_ms: End-to-end processing time in milliseconds.
99
+ """
37
100
 
38
101
  is_complete: bool
39
102
  probability: float
@@ -4,7 +4,13 @@
4
4
  # SPDX-License-Identifier: BSD 2-Clause License
5
5
  #
6
6
 
7
- from abc import abstractmethod
7
+ """Base observer classes for monitoring frame flow in the Pipecat pipeline.
8
+
9
+ This module provides the foundation for observing frame transfers between
10
+ processors without modifying the pipeline structure. Observers can be used
11
+ for logging, debugging, analytics, and monitoring pipeline behavior.
12
+ """
13
+
8
14
  from dataclasses import dataclass
9
15
 
10
16
  from typing_extensions import TYPE_CHECKING
@@ -17,22 +23,44 @@ if TYPE_CHECKING:
17
23
 
18
24
 
19
25
  @dataclass
20
- class FramePushed:
21
- """Represents an event where a frame is pushed from one processor to another
22
- within the pipeline.
26
+ class FrameProcessed:
27
+ """Event data for frame processing in the pipeline.
23
28
 
24
- This data structure is typically used by observers to track the flow of
25
- frames through the pipeline for logging, debugging, or analytics purposes.
29
+ Represents an event where a frame is being processed by a processor. This
30
+ data structure is typically used by observers to track the flow of frames
31
+ through the pipeline for logging, debugging, or analytics purposes.
26
32
 
27
- Attributes:
28
- source (FrameProcessor): The processor sending the frame.
29
- destination (FrameProcessor): The processor receiving the frame.
30
- frame (Frame): The frame being transferred.
31
- direction (FrameDirection): The direction of the transfer (e.g., downstream or upstream).
32
- timestamp (int): The time when the frame was pushed, based on the pipeline clock.
33
+ Parameters:
34
+ processor: The processor processing the frame.
35
+ frame: The frame being processed.
36
+ direction: The direction of the frame (e.g., downstream or upstream).
37
+ timestamp: The time when the frame was pushed, based on the pipeline clock.
33
38
 
34
39
  """
35
40
 
41
+ processor: "FrameProcessor"
42
+ frame: Frame
43
+ direction: "FrameDirection"
44
+ timestamp: int
45
+
46
+
47
+ @dataclass
48
+ class FramePushed:
49
+ """Event data for frame transfers between processors in the pipeline.
50
+
51
+ Represents an event where a frame is pushed from one processor to another
52
+ within the pipeline. This data structure is typically used by observers
53
+ to track the flow of frames through the pipeline for logging, debugging,
54
+ or analytics purposes.
55
+
56
+ Parameters:
57
+ source: The processor sending the frame.
58
+ destination: The processor receiving the frame.
59
+ frame: The frame being transferred.
60
+ direction: The direction of the transfer (e.g., downstream or upstream).
61
+ timestamp: The time when the frame was pushed, based on the pipeline clock.
62
+ """
63
+
36
64
  source: "FrameProcessor"
37
65
  destination: "FrameProcessor"
38
66
  frame: Frame
@@ -41,14 +69,26 @@ class FramePushed:
41
69
 
42
70
 
43
71
  class BaseObserver(BaseObject):
44
- """This is the base class for pipeline frame observers. Observers can view
45
- all the frames that go through the pipeline without the need to inject
46
- processors in the pipeline. This can be useful, for example, to implement
47
- frame loggers or debuggers among other things.
72
+ """Base class for pipeline frame observers.
48
73
 
74
+ Observers can view all frames that flow through the pipeline without
75
+ needing to inject processors into the pipeline structure. This enables
76
+ non-intrusive monitoring capabilities such as frame logging, debugging,
77
+ performance analysis, and analytics collection.
49
78
  """
50
79
 
51
- @abstractmethod
80
+ async def on_process_frame(self, data: FrameProcessed):
81
+ """Handle the event when a frame is being processed by a processor.
82
+
83
+ This method should be implemented by subclasses to define specific
84
+ behavior (e.g., logging, monitoring, debugging) when a frame is
85
+ being processed by a processor.
86
+
87
+ Args:
88
+ data: The event data containing details about the frame processing.
89
+ """
90
+ pass
91
+
52
92
  async def on_push_frame(self, data: FramePushed):
53
93
  """Handle the event when a frame is pushed from one processor to another.
54
94
 
@@ -57,7 +97,6 @@ class BaseObserver(BaseObject):
57
97
  transferred through the pipeline.
58
98
 
59
99
  Args:
60
- data (FramePushed): The event data containing details about the frame transfer.
61
-
100
+ data: The event data containing details about the frame transfer.
62
101
  """
63
102
  pass
@@ -4,6 +4,13 @@
4
4
  # SPDX-License-Identifier: BSD 2-Clause License
5
5
  #
6
6
 
7
+ """Debug logging observer for frame activity monitoring.
8
+
9
+ This module provides a debug observer that logs detailed frame activity
10
+ to the console, making it useful for debugging pipeline behavior and
11
+ understanding frame flow between processors.
12
+ """
13
+
7
14
  from dataclasses import fields, is_dataclass
8
15
  from enum import Enum, auto
9
16
  from typing import Dict, Optional, Set, Tuple, Type, Union
@@ -16,7 +23,12 @@ from pipecat.processors.frame_processor import FrameDirection
16
23
 
17
24
 
18
25
  class FrameEndpoint(Enum):
19
- """Specifies which endpoint (source or destination) to filter on."""
26
+ """Specifies which endpoint (source or destination) to filter on.
27
+
28
+ Parameters:
29
+ SOURCE: Filter on the source component that is pushing the frame.
30
+ DESTINATION: Filter on the destination component receiving the frame.
31
+ """
20
32
 
21
33
  SOURCE = auto()
22
34
  DESTINATION = auto()
@@ -28,44 +40,37 @@ class DebugLogObserver(BaseObserver):
28
40
  Automatically extracts and formats data from any frame type, making it useful
29
41
  for debugging pipeline behavior without needing frame-specific observers.
30
42
 
31
- Args:
32
- frame_types: Optional tuple of frame types to log, or a dict with frame type
33
- filters. If None, logs all frame types.
34
- exclude_fields: Optional set of field names to exclude from logging.
35
-
36
43
  Examples:
37
- Log all frames from all services:
38
- ```python
39
- observers = DebugLogObserver()
40
- ```
41
-
42
- Log specific frame types from any source/destination:
43
- ```python
44
- from pipecat.frames.frames import TranscriptionFrame, InterimTranscriptionFrame
45
- observers=[
46
- DebugLogObserver(frame_types=(LLMTextFrame,TranscriptionFrame,)),
47
- ],
48
- ```
49
-
50
- Log frames with specific source/destination filters:
51
- ```python
52
- from pipecat.frames.frames import StartInterruptionFrame, UserStartedSpeakingFrame, LLMTextFrame
53
- from pipecat.transports.base_output_transport import BaseOutputTransport
54
- from pipecat.services.stt_service import STTService
55
-
56
- observers=[
57
- DebugLogObserver(
58
- frame_types={
59
- # Only log StartInterruptionFrame when source is BaseOutputTransport
60
- StartInterruptionFrame: (BaseOutputTransport, FrameEndpoint.SOURCE),
61
- # Only log UserStartedSpeakingFrame when destination is STTService
62
- UserStartedSpeakingFrame: (STTService, FrameEndpoint.DESTINATION),
63
- # Log LLMTextFrame regardless of source or destination type
64
- LLMTextFrame: None,
65
- }
66
- ),
67
- ],
68
- ```
44
+ Log all frames from all services::
45
+
46
+ observers = DebugLogObserver()
47
+
48
+ Log specific frame types from any source/destination::
49
+
50
+ from pipecat.frames.frames import LLMTextFrame, TranscriptionFrame
51
+ observers=[
52
+ DebugLogObserver(frame_types=(LLMTextFrame,TranscriptionFrame,)),
53
+ ]
54
+
55
+ Log frames with specific source/destination filters::
56
+
57
+ from pipecat.frames.frames import StartInterruptionFrame, UserStartedSpeakingFrame, LLMTextFrame
58
+ from pipecat.observers.loggers.debug_log_observer import DebugLogObserver, FrameEndpoint
59
+ from pipecat.transports.base_output import BaseOutputTransport
60
+ from pipecat.services.stt_service import STTService
61
+
62
+ observers=[
63
+ DebugLogObserver(
64
+ frame_types={
65
+ # Only log StartInterruptionFrame when source is BaseOutputTransport
66
+ StartInterruptionFrame: (BaseOutputTransport, FrameEndpoint.SOURCE),
67
+ # Only log UserStartedSpeakingFrame when destination is STTService
68
+ UserStartedSpeakingFrame: (STTService, FrameEndpoint.DESTINATION),
69
+ # Log LLMTextFrame regardless of source or destination type
70
+ LLMTextFrame: None,
71
+ }
72
+ ),
73
+ ]
69
74
  """
70
75
 
71
76
  def __init__(
@@ -79,14 +84,17 @@ class DebugLogObserver(BaseObserver):
79
84
  """Initialize the debug log observer.
80
85
 
81
86
  Args:
82
- frame_types: Tuple of frame types to log, or a dict mapping frame types to
83
- filter configurations. Filter configs can be:
84
- - None to log all instances of the frame type
85
- - A tuple of (service_type, endpoint) to filter on a specific service
86
- and endpoint (SOURCE or DESTINATION)
87
- If None is provided instead of a tuple/dict, log all frames.
88
- exclude_fields: Set of field names to exclude from logging. If None, only binary
89
- data fields are excluded.
87
+ frame_types: Frame types to log. Can be:
88
+
89
+ - Tuple of frame types to log all instances
90
+ - Dict mapping frame types to filter configurations
91
+ - None to log all frames
92
+
93
+ Filter configurations can be None (log all instances) or a tuple
94
+ of (service_type, endpoint) to filter on specific services.
95
+ exclude_fields: Field names to exclude from logging. Defaults to
96
+ excluding binary data fields like 'audio', 'image', 'images'.
97
+ **kwargs: Additional arguments passed to parent class.
90
98
  """
91
99
  super().__init__(**kwargs)
92
100
 
@@ -113,14 +121,7 @@ class DebugLogObserver(BaseObserver):
113
121
  )
114
122
 
115
123
  def _format_value(self, value):
116
- """Format a value for logging.
117
-
118
- Args:
119
- value: The value to format.
120
-
121
- Returns:
122
- str: A string representation of the value suitable for logging.
123
- """
124
+ """Format a value for logging."""
124
125
  if value is None:
125
126
  return "None"
126
127
  elif isinstance(value, str):
@@ -143,16 +144,7 @@ class DebugLogObserver(BaseObserver):
143
144
  return str(value)
144
145
 
145
146
  def _should_log_frame(self, frame, src, dst):
146
- """Determine if a frame should be logged based on filters.
147
-
148
- Args:
149
- frame: The frame being processed
150
- src: The source component
151
- dst: The destination component
152
-
153
- Returns:
154
- bool: True if the frame should be logged, False otherwise
155
- """
147
+ """Determine if a frame should be logged based on filters."""
156
148
  # If no filters, log all frames
157
149
  if not self.frame_filters:
158
150
  return True
@@ -4,6 +4,8 @@
4
4
  # SPDX-License-Identifier: BSD 2-Clause License
5
5
  #
6
6
 
7
+ """LLM logging observer for Pipecat."""
8
+
7
9
  from loguru import logger
8
10
 
9
11
  from pipecat.frames.frames import (
@@ -34,10 +36,15 @@ class LLMLogObserver(BaseObserver):
34
36
 
35
37
  This allows you to track when the LLM starts responding, what it generates,
36
38
  and when it finishes.
37
-
38
39
  """
39
40
 
40
41
  async def on_push_frame(self, data: FramePushed):
42
+ """Handle frame push events and log LLM-related activities.
43
+
44
+ Args:
45
+ data: The frame push event data containing source, destination,
46
+ frame, direction, and timestamp information.
47
+ """
41
48
  src = data.source
42
49
  dst = data.destination
43
50
  frame = data.frame
@@ -4,6 +4,12 @@
4
4
  # SPDX-License-Identifier: BSD 2-Clause License
5
5
  #
6
6
 
7
+ """Transcription logging observer for Pipecat.
8
+
9
+ This module provides an observer that logs transcription frames to the console,
10
+ allowing developers to monitor speech-to-text activity in real-time.
11
+ """
12
+
7
13
  from loguru import logger
8
14
 
9
15
  from pipecat.frames.frames import (
@@ -17,17 +23,23 @@ from pipecat.services.stt_service import STTService
17
23
  class TranscriptionLogObserver(BaseObserver):
18
24
  """Observer to log transcription activity to the console.
19
25
 
20
- Logs all frame instances (only from STT service) of:
21
-
22
- - TranscriptionFrame
23
- - InterimTranscriptionFrame
24
-
25
- This allows you to track when the LLM starts responding, what it generates,
26
- and when it finishes.
26
+ Monitors and logs all transcription frames from STT services, including
27
+ both final transcriptions and interim results. This allows developers
28
+ to track speech recognition activity and debug transcription issues.
27
29
 
30
+ Only processes frames from STTService instances to avoid logging
31
+ unrelated transcription frames from other sources.
28
32
  """
29
33
 
30
34
  async def on_push_frame(self, data: FramePushed):
35
+ """Handle frame push events and log transcription frames.
36
+
37
+ Logs TranscriptionFrame and InterimTranscriptionFrame instances
38
+ with timestamps and user information for debugging purposes.
39
+
40
+ Args:
41
+ data: Frame push event data containing source, frame, and timestamp.
42
+ """
31
43
  src = data.source
32
44
  frame = data.frame
33
45
  timestamp = data.timestamp
@@ -4,12 +4,17 @@
4
4
  # SPDX-License-Identifier: BSD 2-Clause License
5
5
  #
6
6
 
7
+ """Observer for measuring user-to-bot response latency."""
8
+
7
9
  import time
10
+ from statistics import mean
8
11
 
9
12
  from loguru import logger
10
13
 
11
14
  from pipecat.frames.frames import (
12
15
  BotStartedSpeakingFrame,
16
+ CancelFrame,
17
+ EndFrame,
13
18
  UserStartedSpeakingFrame,
14
19
  UserStoppedSpeakingFrame,
15
20
  )
@@ -18,19 +23,29 @@ from pipecat.processors.frame_processor import FrameDirection
18
23
 
19
24
 
20
25
  class UserBotLatencyLogObserver(BaseObserver):
21
- """Observer that logs the latency between when the user stops speaking and
22
- when the bot starts speaking.
23
-
24
- This helps measure how quickly the AI services respond.
26
+ """Observer that measures time between user stopping speech and bot starting speech.
25
27
 
28
+ This helps measure how quickly the AI services respond by tracking
29
+ conversation turn timing and logging latency metrics.
26
30
  """
27
31
 
28
32
  def __init__(self):
33
+ """Initialize the latency observer.
34
+
35
+ Sets up tracking for processed frames and user speech timing
36
+ to calculate response latencies.
37
+ """
29
38
  super().__init__()
30
39
  self._processed_frames = set()
31
40
  self._user_stopped_time = 0
41
+ self._latencies = []
32
42
 
33
43
  async def on_push_frame(self, data: FramePushed):
44
+ """Process frames to track speech timing and calculate latency.
45
+
46
+ Args:
47
+ data: Frame push event containing the frame and direction information.
48
+ """
34
49
  # Only process downstream frames
35
50
  if data.direction != FrameDirection.DOWNSTREAM:
36
51
  return
@@ -45,6 +60,18 @@ class UserBotLatencyLogObserver(BaseObserver):
45
60
  self._user_stopped_time = 0
46
61
  elif isinstance(data.frame, UserStoppedSpeakingFrame):
47
62
  self._user_stopped_time = time.time()
63
+ elif isinstance(data.frame, (EndFrame, CancelFrame)):
64
+ if self._latencies:
65
+ avg_latency = mean(self._latencies)
66
+ min_latency = min(self._latencies)
67
+ max_latency = max(self._latencies)
68
+ logger.info(
69
+ f"⏱️ LATENCY FROM USER STOPPED SPEAKING TO BOT STARTED SPEAKING - Avg: {avg_latency:.3f}s, Min: {min_latency:.3f}s, Max: {max_latency:.3f}s"
70
+ )
48
71
  elif isinstance(data.frame, BotStartedSpeakingFrame) and self._user_stopped_time:
49
72
  latency = time.time() - self._user_stopped_time
50
- logger.debug(f"⏱️ LATENCY FROM USER STOPPED SPEAKING TO BOT STARTED SPEAKING: {latency}")
73
+ self._user_stopped_time = 0
74
+ self._latencies.append(latency)
75
+ logger.debug(
76
+ f"⏱️ LATENCY FROM USER STOPPED SPEAKING TO BOT STARTED SPEAKING: {latency:.3f}s"
77
+ )
@@ -4,6 +4,12 @@
4
4
  # SPDX-License-Identifier: BSD 2-Clause License
5
5
  #
6
6
 
7
+ """Turn tracking observer for conversation flow monitoring.
8
+
9
+ This module provides an observer that monitors conversation turns in a pipeline,
10
+ tracking when turns start and end based on user and bot speech patterns.
11
+ """
12
+
7
13
  import asyncio
8
14
  from collections import deque
9
15
 
@@ -23,15 +29,30 @@ from pipecat.observers.base_observer import BaseObserver, FramePushed
23
29
  class TurnTrackingObserver(BaseObserver):
24
30
  """Observer that tracks conversation turns in a pipeline.
25
31
 
32
+ This observer monitors the flow of conversation by tracking when turns
33
+ start and end based on user and bot speaking patterns. It handles
34
+ interruptions, timeouts, and maintains turn state throughout the pipeline.
35
+
26
36
  Turn tracking logic:
37
+
27
38
  - The first turn starts immediately when the pipeline starts (StartFrame)
28
39
  - Subsequent turns start when the user starts speaking
29
40
  - A turn ends when the bot stops speaking and either:
41
+
30
42
  - The user starts speaking again
31
43
  - A timeout period elapses with no more bot speech
32
44
  """
33
45
 
34
46
  def __init__(self, max_frames=100, turn_end_timeout_secs=2.5, **kwargs):
47
+ """Initialize the turn tracking observer.
48
+
49
+ Args:
50
+ max_frames: Maximum number of frame IDs to keep in history for
51
+ duplicate detection. Defaults to 100.
52
+ turn_end_timeout_secs: Timeout in seconds after bot stops speaking
53
+ before automatically ending the turn. Defaults to 2.5.
54
+ **kwargs: Additional arguments passed to the parent observer.
55
+ """
35
56
  super().__init__(**kwargs)
36
57
  self._turn_count = 0
37
58
  self._is_turn_active = False
@@ -49,7 +70,11 @@ class TurnTrackingObserver(BaseObserver):
49
70
  self._register_event_handler("on_turn_ended")
50
71
 
51
72
  async def on_push_frame(self, data: FramePushed):
52
- """Process frame events for turn tracking."""
73
+ """Process frame events for turn tracking.
74
+
75
+ Args:
76
+ data: Frame push event data containing the frame and metadata.
77
+ """
53
78
  # Skip already processed frames
54
79
  if data.frame.id in self._processed_frames:
55
80
  return
@@ -4,16 +4,14 @@
4
4
  # SPDX-License-Identifier: BSD 2-Clause License
5
5
  #
6
6
 
7
- from abc import abstractmethod
8
- from typing import List
7
+ """Base pipeline implementation for frame processing."""
9
8
 
10
9
  from pipecat.processors.frame_processor import FrameProcessor
11
10
 
12
11
 
13
12
  class BasePipeline(FrameProcessor):
14
- def __init__(self):
15
- super().__init__()
13
+ """Base class for all pipeline implementations."""
16
14
 
17
- @abstractmethod
18
- def processors_with_metrics(self) -> List[FrameProcessor]:
19
- pass
15
+ def __init__(self, **kwargs):
16
+ """Initialize the base pipeline."""
17
+ super().__init__(**kwargs)