dv-pipecat-ai 0.0.75.dev840__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.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dv-pipecat-ai
3
- Version: 0.0.75.dev840
3
+ Version: 0.0.82.dev776
4
4
  Summary: An open source framework for voice (and multimodal) assistants
5
5
  License-Expression: BSD-2-Clause
6
6
  Project-URL: Source, https://github.com/pipecat-ai/pipecat
@@ -1,4 +1,4 @@
1
- dv_pipecat_ai-0.0.75.dev840.dist-info/licenses/LICENSE,sha256=DWY2QGf2eMCFhuu2ChairtT6CB7BEFffNVhXWc4Od08,1301
1
+ dv_pipecat_ai-0.0.82.dev776.dist-info/licenses/LICENSE,sha256=DWY2QGf2eMCFhuu2ChairtT6CB7BEFffNVhXWc4Od08,1301
2
2
  pipecat/__init__.py,sha256=j0Xm6adxHhd7D06dIyyPV_GlBYLlBnTAERVvD_jAARQ,861
3
3
  pipecat/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  pipecat/adapters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -93,7 +93,7 @@ pipecat/processors/aggregators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5
93
93
  pipecat/processors/aggregators/dtmf_aggregator.py,sha256=x2Q8hSFeh_O0B7D7umSV8CDMNduZG2jjBxa6miR-yiU,5308
94
94
  pipecat/processors/aggregators/gated.py,sha256=tii0sRrBkRW6y9Xq5iTWPnqlOEejU4VqPIPtdOa61pc,3073
95
95
  pipecat/processors/aggregators/gated_openai_llm_context.py,sha256=cr6MT8J6SpPzZbppKPOKe3_pt_5qXC9g6a4wvZDyrec,3005
96
- pipecat/processors/aggregators/llm_response.py,sha256=SA6_ec2276ij66Kb9Am5XvQ9lcbVHB7ThMLr9wpkqNg,46224
96
+ pipecat/processors/aggregators/llm_response.py,sha256=Ki_xWxPda2N0HCg7eC0Z9Apa6sqxm97Jixc_y8fHw1c,46321
97
97
  pipecat/processors/aggregators/openai_llm_context.py,sha256=82q67TsjoAPSESAjzHI5jE9Ffq7yiB3MRtxy71V2RGg,12984
98
98
  pipecat/processors/aggregators/sentence.py,sha256=E7e3knfQl6HEGpYMKPklF1aO_gOn-rr7SnynErwfkQk,2235
99
99
  pipecat/processors/aggregators/user_response.py,sha256=Jw_54IVZ47S_GU3P_SSU4L2l5J7AiehzU1L5JwiaRJo,1784
@@ -126,6 +126,7 @@ pipecat/serializers/__init__.py,sha256=OV61GQX5ZVU7l7Dt7UTBdv2wUF7ZvtbCoXryo7nno
126
126
  pipecat/serializers/base_serializer.py,sha256=OyBUZccs2ZT9mfkBbq2tGsUJMvci6o-j90Cl1sicPaI,2030
127
127
  pipecat/serializers/convox.py,sha256=MXCLhV6GMnoP8bI6-EVrObhrftEyTGOmzVeIU5ywmPo,9536
128
128
  pipecat/serializers/exotel.py,sha256=LB4wYoXDjPmtkydrZ0G4H4u-SXpQw9KjyRzBZCYloEE,5907
129
+ pipecat/serializers/genesys.py,sha256=5g6_F-OIWSNmStgc6-bDT5mDQkCHHKxcOWSb-F4s2-A,3564
129
130
  pipecat/serializers/livekit.py,sha256=caVZlVJGV-SmEXE_H7i3DRo1RvC9FgGCVqi8IYGrpEo,2552
130
131
  pipecat/serializers/plivo.py,sha256=EXZZgwxQzhO61spRU98qveMskVnELuHCQg5piBO6tq0,9210
131
132
  pipecat/serializers/protobuf.py,sha256=h0UgVvIa3LXxtpbeQUq0tCGicGbDHxjiY6EdxXJO0_s,5162
@@ -135,7 +136,7 @@ pipecat/services/__init__.py,sha256=B0B4BXpPNgYTf0orYxQvdhSyvtZwNj9Whqndgav4r4E,
135
136
  pipecat/services/ai_service.py,sha256=mck03zv_-NZ39jhHR3hT_Qu5s6s_JzQ88lpiCtRV87w,5980
136
137
  pipecat/services/ai_services.py,sha256=_RrDWfM8adV17atzY9RxK0nXRVM5kbUkKrvN90GAWYM,795
137
138
  pipecat/services/image_service.py,sha256=tqJun4nYeyN_PaWqTdF_CFsOiqBf3XX7R4et5Y07mEU,2357
138
- pipecat/services/llm_service.py,sha256=ybvMa4iqOhdNtlSCFKZJSKug6Jx8GhucsQ_7a9MXBf0,23595
139
+ pipecat/services/llm_service.py,sha256=VUzdf9mP8P9hdKwi2P544vwZOJHzB8ExfTAaKYKcmm8,23704
139
140
  pipecat/services/mcp_service.py,sha256=OYftGfdfGlDmjsWbF2b3CuMhPw8B1jcgaZUUYZPIA_o,14298
140
141
  pipecat/services/openai.py,sha256=fg5-MIvwqgKTN6i5Kp7GD6XUvMRo3nlughuNt9QqLGA,27546
141
142
  pipecat/services/stt_service.py,sha256=tShjVEl374j1Sc3qsdhTuWaT-8NJsAn-3yFw0XLRm4A,11163
@@ -200,6 +201,7 @@ pipecat/services/google/llm_openai.py,sha256=p_aQYpX1e_ffO63oo0cDyj8ZYWb2CO3N-Ii
200
201
  pipecat/services/google/llm_vertex.py,sha256=yqs8pqUCTgRj5wvQFHPJbGduoIaXjaqPym5x-lh5LhI,5032
201
202
  pipecat/services/google/rtvi.py,sha256=PZb1yVny5YG7_XmJRXPzs3iYapeQ4XHreFN1v6KwTGM,3014
202
203
  pipecat/services/google/stt.py,sha256=1vKZNEKZ-KLKp_7lA_VijznSqTwYRFYK1sDn2qteKtI,32814
204
+ pipecat/services/google/test-google-chirp.py,sha256=ji6ta7WDgKMu9yeKovuIVRlcMuk8S6XIyzIokHQY80E,1437
203
205
  pipecat/services/google/tts.py,sha256=S_JSPqzLABfuyHLRppNiDmq2g9OFcnJOrfysVg3OHbY,32038
204
206
  pipecat/services/grok/__init__.py,sha256=PyaTSnqwxd8jdF5aFTe3lWM-TBhfDyUu9ahRl6nPS-4,251
205
207
  pipecat/services/grok/llm.py,sha256=xsJWXqJApfQgEt6z_8U44qUCQJMcpgEdpOHN-u0tNAQ,7330
@@ -332,7 +334,7 @@ pipecat/utils/tracing/service_decorators.py,sha256=HwDCqLGijhYD3F8nxDuQmEw-YkRw0
332
334
  pipecat/utils/tracing/setup.py,sha256=7TEgPNpq6M8lww8OQvf0P9FzYc5A30xICGklVA-fua0,2892
333
335
  pipecat/utils/tracing/turn_context_provider.py,sha256=ikon3plFOx0XbMrH6DdeHttNpb-U0gzMZIm3bWLc9eI,2485
334
336
  pipecat/utils/tracing/turn_trace_observer.py,sha256=dma16SBJpYSOE58YDWy89QzHyQFc_9gQZszKeWixuwc,9725
335
- dv_pipecat_ai-0.0.75.dev840.dist-info/METADATA,sha256=6BnxCiDkrqjYv7q2PmXwWBwL33GrUm4nrTu0em3yFlY,32457
336
- dv_pipecat_ai-0.0.75.dev840.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
337
- dv_pipecat_ai-0.0.75.dev840.dist-info/top_level.txt,sha256=kQzG20CxGf-nSsHmtXHx3hY2-8zHA3jYg8jk0TajqXc,8
338
- dv_pipecat_ai-0.0.75.dev840.dist-info/RECORD,,
337
+ dv_pipecat_ai-0.0.82.dev776.dist-info/METADATA,sha256=VJAth6kEBgJT2SJHJ5KnMorgpHZvF6ZMg6Uqc65CL-Q,32457
338
+ dv_pipecat_ai-0.0.82.dev776.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
339
+ dv_pipecat_ai-0.0.82.dev776.dist-info/top_level.txt,sha256=kQzG20CxGf-nSsHmtXHx3hY2-8zHA3jYg8jk0TajqXc,8
340
+ dv_pipecat_ai-0.0.82.dev776.dist-info/RECORD,,
@@ -541,7 +541,8 @@ class LLMUserContextAggregator(LLMContextResponseAggregator):
541
541
  self.logger.debug(
542
542
  "Triggering interruption - pushing BotInterruptionFrame and aggregation"
543
543
  )
544
- await self.push_frame(BotInterruptionFrame(), FrameDirection.UPSTREAM)
544
+ # await self.push_frame(BotInterruptionFrame(), FrameDirection.UPSTREAM)
545
+ await self.push_frame(StartInterruptionFrame(), FrameDirection.DOWNSTREAM)
545
546
  self.logger.debug("Pushed BotInterruptionFrame")
546
547
  # No interruption config - normal behavior (always push aggregation)
547
548
  await self._process_aggregation()
@@ -0,0 +1,95 @@
1
+ import base64
2
+ import json
3
+ from typing import Optional
4
+
5
+ from pydantic import BaseModel
6
+
7
+ from pipecat.audio.utils import create_default_resampler, pcm_to_ulaw, ulaw_to_pcm
8
+ from pipecat.frames.frames import (
9
+ AudioRawFrame,
10
+ Frame,
11
+ InputAudioRawFrame,
12
+ InputDTMFFrame,
13
+ KeypadEntry,
14
+ StartFrame,
15
+ StartInterruptionFrame,
16
+ TransportMessageFrame,
17
+ TransportMessageUrgentFrame,
18
+ )
19
+ from pipecat.serializers.base_serializer import FrameSerializer, FrameSerializerType
20
+
21
+
22
+ class GenesysFrameSerializer(FrameSerializer):
23
+ class InputParams(BaseModel):
24
+ genesys_sample_rate: int = 8000 # Default Genesys rate (8kHz)
25
+ sample_rate: Optional[int] = None # Pipeline input rate
26
+
27
+ def __init__(self, session_id: str, params: InputParams = InputParams()):
28
+ self._session_id = session_id
29
+ self._params = params
30
+ self._genesys_sample_rate = self._params.genesys_sample_rate
31
+ self._sample_rate = 0 # Pipeline input rate
32
+ self._resampler = create_default_resampler()
33
+ self._seq = 1 # Sequence number for outgoing messages
34
+
35
+ @property
36
+ def type(self) -> FrameSerializerType:
37
+ return FrameSerializerType.TEXT
38
+
39
+ async def setup(self, frame: StartFrame):
40
+ self._sample_rate = self._params.sample_rate or frame.audio_in_sample_rate
41
+
42
+ async def serialize(self, frame: Frame) -> str | bytes | None:
43
+ if isinstance(frame, StartInterruptionFrame):
44
+ answer = {
45
+ "version": "2",
46
+ "type": "clearAudio", # Or appropriate event for interruption
47
+ "seq": self._seq,
48
+ "id": self._session_id,
49
+ }
50
+ self._seq += 1
51
+ return json.dumps(answer)
52
+ elif isinstance(frame, AudioRawFrame):
53
+ data = frame.audio
54
+ # Convert PCM to 8kHz μ-law for Genesys
55
+ serialized_data = await pcm_to_ulaw(
56
+ data, frame.sample_rate, self._genesys_sample_rate, self._resampler
57
+ )
58
+ payload = base64.b64encode(serialized_data).decode("utf-8")
59
+ answer = {
60
+ "version": "2",
61
+ "type": "audio",
62
+ "seq": self._seq,
63
+ "id": self._session_id,
64
+ "media": {
65
+ "payload": payload,
66
+ "format": "PCMU",
67
+ "rate": self._genesys_sample_rate,
68
+ },
69
+ }
70
+ self._seq += 1
71
+ return json.dumps(answer)
72
+ elif isinstance(frame, (TransportMessageFrame, TransportMessageUrgentFrame)):
73
+ return json.dumps(frame.message)
74
+
75
+ async def deserialize(self, data: str | bytes) -> Frame | None:
76
+ message = json.loads(data)
77
+ if message.get("type") == "audio":
78
+ payload_base64 = message["media"]["payload"]
79
+ payload = base64.b64decode(payload_base64)
80
+ # Convert Genesys 8kHz μ-law to PCM at pipeline input rate
81
+ deserialized_data = await ulaw_to_pcm(
82
+ payload, self._genesys_sample_rate, self._sample_rate, self._resampler
83
+ )
84
+ audio_frame = InputAudioRawFrame(
85
+ audio=deserialized_data, num_channels=1, sample_rate=self._sample_rate
86
+ )
87
+ return audio_frame
88
+ elif message.get("type") == "dtmf":
89
+ digit = message.get("dtmf", {}).get("digit")
90
+ try:
91
+ return InputDTMFFrame(KeypadEntry(digit))
92
+ except ValueError:
93
+ return None
94
+ else:
95
+ return None
@@ -0,0 +1,45 @@
1
+ import asyncio
2
+ import os
3
+
4
+ from pipecat.frames.frames import TTSAudioRawFrame
5
+ from pipecat.services.google.tts import GoogleTTSService
6
+
7
+
8
+ async def test_chirp_tts():
9
+ # Get credentials from environment variable
10
+ credentials_path = (
11
+ "/Users/kalicharanvemuru/Documents/Code/pipecat/examples/ringg-chatbot/creds.json"
12
+ )
13
+
14
+ if not credentials_path or not os.path.exists(credentials_path):
15
+ raise ValueError(
16
+ "Please set GOOGLE_APPLICATION_CREDENTIALS environment variable to your service account key file"
17
+ )
18
+
19
+ # Initialize the TTS service with Chirp voice
20
+ tts = GoogleTTSService(
21
+ credentials_path=credentials_path,
22
+ voice_id="en-US-Chirp3-HD-Charon", # Using Chirp3 HD Charon voice
23
+ sample_rate=24000,
24
+ )
25
+
26
+ # Test text
27
+ test_text = "Hello, this is a test of the Google TTS service with Chirp voice."
28
+
29
+ print(f"Testing TTS with text: {test_text}")
30
+
31
+ # Generate speech
32
+ try:
33
+ async for frame in tts.run_tts(test_text):
34
+ if isinstance(frame, TTSAudioRawFrame):
35
+ print(f"Received audio chunk of size: {len(frame.audio)} bytes")
36
+ else:
37
+ print(f"Received frame: {frame.__class__.__name__}")
38
+
39
+ print("TTS generation completed successfully!")
40
+ except Exception as e:
41
+ print(f"Error during TTS generation: {str(e)}")
42
+
43
+
44
+ if __name__ == "__main__":
45
+ asyncio.run(test_chirp_tts())
@@ -254,9 +254,11 @@ class LLMService(AIService):
254
254
  await self._handle_interruptions(frame)
255
255
 
256
256
  async def _handle_interruptions(self, _: StartInterruptionFrame):
257
+ # logger.info("In LLM Handling interruptions")
257
258
  for function_name, entry in self._functions.items():
258
259
  if entry.cancel_on_interruption:
259
260
  await self._cancel_function_call(function_name)
261
+ # logger.info("in LLM Interruptions handled")
260
262
 
261
263
  def register_function(
262
264
  self,