From 3f4814cf84cdc108752cfae45a0ad92c81e5fc3a Mon Sep 17 00:00:00 2001
From: Mark Backman
Date: Mon, 30 Mar 2026 14:15:06 -0400
Subject: [PATCH 01/19] Fix UTF-8 decode error in Inworld TTS streaming
response
Buffer raw bytes and only decode after splitting on newline boundaries,
preventing multi-byte UTF-8 characters from being split at chunk edges.
Fixes #3538
---
src/pipecat/services/inworld/tts.py | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/pipecat/services/inworld/tts.py b/src/pipecat/services/inworld/tts.py
index 157130442..215c0f747 100644
--- a/src/pipecat/services/inworld/tts.py
+++ b/src/pipecat/services/inworld/tts.py
@@ -387,16 +387,16 @@ class InworldHttpTTSService(TTSService):
Yields:
An asynchronous generator of frames.
"""
- buffer = ""
+ buffer = b""
# Track the duration of this utterance based on the last word's end time
utterance_duration = 0.0
- async for chunk in response.content.iter_chunked(1024):
- buffer += chunk.decode("utf-8")
+ async for chunk in response.content.iter_any():
+ buffer += chunk
- while "\n" in buffer:
- line, buffer = buffer.split("\n", 1)
- line_str = line.strip()
+ while b"\n" in buffer:
+ line, buffer = buffer.split(b"\n", 1)
+ line_str = line.decode("utf-8").strip()
if not line_str:
continue
From 465b9bcbc6bd1cb7ac7f22b9efe29d8fe3b27948 Mon Sep 17 00:00:00 2001
From: Mark Backman
Date: Mon, 30 Mar 2026 14:16:21 -0400
Subject: [PATCH 02/19] Add changelog for #4202
---
changelog/4202.fixed.md | 1 +
1 file changed, 1 insertion(+)
create mode 100644 changelog/4202.fixed.md
diff --git a/changelog/4202.fixed.md b/changelog/4202.fixed.md
new file mode 100644
index 000000000..7540f453f
--- /dev/null
+++ b/changelog/4202.fixed.md
@@ -0,0 +1 @@
+- Fixed `InworldHttpTTSService` streaming responses crashing with `UnicodeDecodeError` when multi-byte UTF-8 characters were split across chunk boundaries. This caused TTS audio to cut off mid-sentence intermittently.
From 4adf0fd585c57cdc4301ac37c93d7a913c1aae78 Mon Sep 17 00:00:00 2001
From: Mark Backman
Date: Mon, 30 Mar 2026 14:24:04 -0400
Subject: [PATCH 03/19] Handle incomplete function call arguments from
interrupted LLM streams
When a user interruption causes the LLM chunk stream to exit early,
function call arguments may be incomplete JSON. Wrap json.loads() in
try/except JSONDecodeError to skip malformed function calls with a
warning instead of crashing. Fixes #2461.
---
src/pipecat/services/google/openai/llm.py | 6 +++++-
src/pipecat/services/openai/base_llm.py | 6 +++++-
src/pipecat/services/sambanova/llm.py | 6 +++++-
3 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/src/pipecat/services/google/openai/llm.py b/src/pipecat/services/google/openai/llm.py
index da5d1be7a..08a7bcd1b 100644
--- a/src/pipecat/services/google/openai/llm.py
+++ b/src/pipecat/services/google/openai/llm.py
@@ -199,7 +199,11 @@ class GoogleLLMOpenAIBetaService(OpenAILLMService):
# which currently results in an empty function name('').
continue
- arguments = json.loads(arguments)
+ try:
+ arguments = json.loads(arguments)
+ except json.JSONDecodeError:
+ logger.warning(f"{self}: Failed to parse function call arguments: {arguments}")
+ continue
function_calls.append(
FunctionCallFromLLM(
diff --git a/src/pipecat/services/openai/base_llm.py b/src/pipecat/services/openai/base_llm.py
index c06ed3afd..5b444aea1 100644
--- a/src/pipecat/services/openai/base_llm.py
+++ b/src/pipecat/services/openai/base_llm.py
@@ -567,7 +567,11 @@ class BaseOpenAILLMService(LLMService):
for function_name, arguments, tool_id in zip(
functions_list, arguments_list, tool_id_list
):
- arguments = json.loads(arguments)
+ try:
+ arguments = json.loads(arguments)
+ except json.JSONDecodeError:
+ logger.warning(f"{self}: Failed to parse function call arguments: {arguments}")
+ continue
function_calls.append(
FunctionCallFromLLM(
context=context,
diff --git a/src/pipecat/services/sambanova/llm.py b/src/pipecat/services/sambanova/llm.py
index 20e17b4f2..63f37cb43 100644
--- a/src/pipecat/services/sambanova/llm.py
+++ b/src/pipecat/services/sambanova/llm.py
@@ -245,7 +245,11 @@ class SambaNovaLLMService(OpenAILLMService): # type: ignore
if len(arguments) < 1:
continue
- arguments = json.loads(arguments)
+ try:
+ arguments = json.loads(arguments)
+ except json.JSONDecodeError:
+ logger.warning(f"{self}: Failed to parse function call arguments: {arguments}")
+ continue
function_calls.append(
FunctionCallFromLLM(
context=context,
From ea39389e03f18b8b0783c3137fca9fd0ba1c559c Mon Sep 17 00:00:00 2001
From: Mark Backman
Date: Mon, 30 Mar 2026 14:24:49 -0400
Subject: [PATCH 04/19] Add changelog for #4203
---
changelog/4203.fixed.md | 1 +
1 file changed, 1 insertion(+)
create mode 100644 changelog/4203.fixed.md
diff --git a/changelog/4203.fixed.md b/changelog/4203.fixed.md
new file mode 100644
index 000000000..170b559bd
--- /dev/null
+++ b/changelog/4203.fixed.md
@@ -0,0 +1 @@
+- Fixed a crash (`JSONDecodeError`) when a user interruption occurs while the LLM is streaming function call arguments. Previously, the incomplete JSON arguments were passed directly to `json.loads()`, causing an unhandled exception. Affected services: OpenAI, Google (OpenAI-compatible), and SambaNova.
From bf1856f61019345ea9591f154eb031726f886d63 Mon Sep 17 00:00:00 2001
From: Mark Backman
Date: Mon, 30 Mar 2026 21:39:19 -0400
Subject: [PATCH 05/19] Change GrokLLMService default model from grok-3-beta to
grok-3
The grok-3 model is now generally available, so update the default
from the beta variant.
---
src/pipecat/services/xai/llm.py | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/pipecat/services/xai/llm.py b/src/pipecat/services/xai/llm.py
index 160ad3331..6fc274a6d 100644
--- a/src/pipecat/services/xai/llm.py
+++ b/src/pipecat/services/xai/llm.py
@@ -102,7 +102,7 @@ class GrokLLMService(OpenAILLMService):
Args:
api_key: The API key for accessing Grok's API.
base_url: The base URL for Grok API. Defaults to "https://api.x.ai/v1".
- model: The model identifier to use. Defaults to "grok-3-beta".
+ model: The model identifier to use. Defaults to "grok-3".
.. deprecated:: 0.0.105
Use ``settings=GrokLLMService.Settings(model=...)`` instead.
@@ -112,7 +112,9 @@ class GrokLLMService(OpenAILLMService):
**kwargs: Additional keyword arguments passed to OpenAILLMService.
"""
# 1. Initialize default_settings with hardcoded defaults
- default_settings = self.Settings(model="grok-3-beta")
+ default_settings = self.Settings(
+ model="grok-3",
+ )
# 2. Apply direct init arg overrides (deprecated)
if model is not None:
From 7d8b436018bf129d58f3221b38aa89bfd12659c2 Mon Sep 17 00:00:00 2001
From: Mark Backman
Date: Mon, 30 Mar 2026 21:40:16 -0400
Subject: [PATCH 06/19] Add changelog for #4209
---
changelog/4209.changed.md | 1 +
1 file changed, 1 insertion(+)
create mode 100644 changelog/4209.changed.md
diff --git a/changelog/4209.changed.md b/changelog/4209.changed.md
new file mode 100644
index 000000000..a7bd53ca3
--- /dev/null
+++ b/changelog/4209.changed.md
@@ -0,0 +1 @@
+- Changed `GrokLLMService` default model from `grok-3-beta` to `grok-3`, now that the model is generally available.
From f2ce7ececc62dccb47a3c5965174474085da937a Mon Sep 17 00:00:00 2001
From: Mark Backman
Date: Mon, 30 Mar 2026 19:34:29 -0400
Subject: [PATCH 07/19] Move foundational examples to examples/
---
.claude/skills/cleanup/SKILL.md | 2 +-
COMMUNITY_INTEGRATIONS.md | 2 +-
README.md | 4 +-
.../01-say-one-thing-piper.py | 0
.../01-say-one-thing-rime.py | 0
.../{foundational => }/01-say-one-thing.py | 0
.../{foundational => }/01a-local-audio.py | 0
.../{foundational => }/01b-livekit-audio.py | 0
.../{foundational => }/01c-nvidia-riva-tts.py | 0
.../02-llm-say-one-thing.py | 0
examples/{foundational => }/03-still-frame.py | 0
.../03a-local-still-frame.py | 0
.../03b-still-frame-imagen.py | 0
.../04-transports-small-webrtc.py | 0
.../04a-transports-daily.py | 0
.../04b-transports-livekit.py | 0
.../05-sync-speech-and-image.py | 0
.../06-listen-and-respond.py | 0
examples/{foundational => }/06a-image-sync.py | 0
.../07-interruptible-cartesia-http.py | 0
.../07-interruptible-openai-responses-http.py | 0
.../07-interruptible-openai-responses.py | 0
.../{foundational => }/07-interruptible.py | 0
.../07a-interruptible-speechmatics-vad.py | 0
.../07a-interruptible-speechmatics.py | 0
.../07b-interruptible-langchain.py | 0
...c-interruptible-deepgram-flux-sagemaker.py | 0
.../07c-interruptible-deepgram-flux.py | 0
.../07c-interruptible-deepgram-http.py | 0
.../07c-interruptible-deepgram-sagemaker.py | 0
.../07c-interruptible-deepgram-vad.py | 0
.../07c-interruptible-deepgram.py | 0
.../07d-interruptible-elevenlabs-http.py | 0
.../07d-interruptible-elevenlabs.py | 0
.../07e-interruptible-xai.py | 0
.../07f-interruptible-azure-http.py | 0
.../07f-interruptible-azure.py | 0
.../07g-interruptible-openai-http.py | 0
.../07g-interruptible-openai.py | 0
.../07i-interruptible-xtts.py | 0
.../07j-interruptible-gladia-vad.py | 0
.../07j-interruptible-gladia.py | 0
.../07k-interruptible-lmnt.py | 0
.../07l-interruptible-groq.py | 0
.../07m-interruptible-aws-strands.py | 0
.../07m-interruptible-aws.py | 0
.../07n-interruptible-gemini-image.py | 3 -
.../07n-interruptible-gemini.py | 0
.../07n-interruptible-google-http.py | 0
.../07n-interruptible-google.py | 0
...interruptible-assemblyai-turn-detection.py | 0
.../07o-interruptible-assemblyai.py | 0
.../07p-interruptible-krisp-viva.py | 0
.../07q-interruptible-rime-http.py | 0
.../07q-interruptible-rime.py | 0
.../07r-interruptible-nvidia.py | 0
.../07s-interruptible-google-audio-in.py | 0
.../07t-interruptible-fish.py | 0
.../07v-interruptible-neuphonic-http.py | 0
.../07v-interruptible-neuphonic.py | 0
.../07w-interruptible-fal.py | 0
.../07x-interruptible-local.py | 0
.../07y-interruptible-minimax.py | 0
.../07z-interruptible-sarvam-http.py | 0
.../07z-interruptible-sarvam.py | 0
.../07za-interruptible-soniox.py | 0
.../07zb-interruptible-inworld-http.py | 0
.../07zb-interruptible-inworld.py | 0
.../07zc-interruptible-asyncai-http.py | 0
.../07zc-interruptible-asyncai.py | 0
.../07zd-interruptible-aicoustics.py | 0
.../07ze-interruptible-hume.py | 0
.../07zf-interruptible-gradium.py | 0
.../07zg-interruptible-camb.py | 0
.../07zi-interruptible-piper.py | 0
.../07zj-interruptible-kokoro.py | 0
.../07zk-interruptible-resemble.py | 0
.../07zl-interruptible-smallest.py | 0
.../08-custom-frame-processor.py | 0
examples/{foundational => }/09-mirror.py | 0
.../{foundational => }/09a-local-mirror.py | 0
examples/{foundational => }/10-wake-phrase.py | 0
.../{foundational => }/11-sound-effects.py | 0
...12-describe-image-openai-responses-http.py | 0
.../12-describe-image-openai-responses.py | 0
.../12-describe-image-openai.py | 0
.../12a-describe-image-anthropic.py | 0
.../12b-describe-image-aws.py | 0
.../12c-describe-image-gemini-flash.py | 0
.../12d-describe-image-moondream.py | 0
.../13-whisper-transcription.py | 0
.../{foundational => }/13a-whisper-local.py | 0
.../13b-deepgram-transcription.py | 0
.../13c-gladia-transcription.py | 0
.../13c-gladia-translation.py | 0
.../13d-assemblyai-transcription.py | 0
.../{foundational => }/13e-whisper-mlx.py | 0
.../13f-cartesia-transcription.py | 0
.../13h-speechmatics-transcription.py | 0
.../13i-soniox-transcription.py | 0
.../13j-azure-transcription.py | 0
.../13k-elevenlabs-transcription.py | 0
.../13l-gradium-transcription.py | 0
.../13m-openai-transcription.py | 0
...-function-calling-openai-responses-http.py | 0
.../14-function-calling-openai-responses.py | 0
.../{foundational => }/14-function-calling.py | 0
.../14a-function-calling-anthropic.py | 0
.../14b-function-calling-openai.py | 0
.../14c-function-calling-together.py | 0
.../14d-function-calling-anthropic-video.py | 0
.../14d-function-calling-aws-video.py | 0
...14d-function-calling-gemini-flash-video.py | 0
.../14d-function-calling-moondream-video.py | 0
...ion-calling-openai-responses-video-http.py | 0
...function-calling-openai-responses-video.py | 0
.../14d-function-calling-openai-video.py | 0
.../14e-function-calling-google.py | 0
.../14f-function-calling-groq.py | 0
.../14g-function-calling-grok.py | 0
.../14h-function-calling-azure.py | 0
.../14i-function-calling-fireworks.py | 0
.../14j-function-calling-nvidia.py | 0
.../14k-function-calling-cerebras.py | 0
.../14l-function-calling-deepseek.py | 0
.../14m-function-calling-openrouter.py | 0
.../14n-function-calling-perplexity.py | 0
...o-function-calling-gemini-openai-format.py | 0
.../14p-function-calling-gemini-vertex-ai.py | 0
.../14q-function-calling-qwen.py | 0
.../14r-function-calling-aws.py | 0
.../14s-function-calling-sambanova.py | 0
.../14t-function-calling-direct.py | 0
.../14u-function-calling-ollama.py | 0
.../14v-function-calling-nebius.py | 0
.../14w-function-calling-mistral.py | 0
.../14y-function-calling-sarvam.py | 0
.../14z-function-calling-novita.py | 0
.../{foundational => }/15-switch-voices.py | 0
.../15a-switch-languages.py | 0
.../16-gpu-container-local-bot.py | 0
.../{foundational => }/17-detect-user-idle.py | 0
.../18-gstreamer-filesrc.py | 0
.../18a-gstreamer-videotestsrc.py | 0
.../19-openai-realtime-beta.py | 0
.../{foundational => }/19-openai-realtime.py | 0
.../19a-azure-realtime-beta.py | 0
.../{foundational => }/19a-azure-realtime.py | 0
.../19b-openai-realtime-beta-text.py | 0
.../19b-openai-realtime-text.py | 0
.../19c-openai-realtime-live-video.py | 0
...ersistent-context-openai-responses-http.py | 0
...20a-persistent-context-openai-responses.py | 0
.../20a-persistent-context-openai.py | 0
...persistent-context-openai-realtime-beta.py | 0
.../20b-persistent-context-openai-realtime.py | 0
.../20c-persistent-context-anthropic.py | 0
.../20d-persistent-context-gemini.py | 0
.../20e-persistent-context-aws-nova-sonic.py | 0
.../20f-persistent-context-grok-realtime.py | 0
.../{foundational => }/21-tavus-transport.py | 0
.../21a-tavus-video-service.py | 0
.../22-filter-incomplete-turns.py | 0
.../23-bot-background-sound.py | 0
.../24-user-mute-strategy.py | 0
.../{foundational => }/25-google-audio-in.py | 0
examples/{foundational => }/26-gemini-live.py | 0
.../26a-gemini-live-local-vad.py | 0
.../26b-gemini-live-function-calling.py | 0
.../26c-gemini-live-video.py | 0
.../26e-gemini-live-google-search.py | 0
.../26f-gemini-live-files-api.py | 0
.../26g-gemini-live-groundingMetadata.py | 0
...26h-gemini-live-vertex-function-calling.py | 0
.../26i-gemini-live-graceful-end.py | 0
examples/{foundational => }/27-simli-layer.py | 0
.../28-user-assistant-turns.py | 0
.../29-turn-tracking-observer.py | 0
examples/{foundational => }/30-observer.py | 0
examples/{foundational => }/31-heartbeats.py | 0
.../32-gemini-grounding-metadata.py | 0
examples/{foundational => }/33-gemini-rag.py | 0
.../{foundational => }/34-audio-recording.py | 0
.../35-pattern-pair-voice-switching.py | 0
.../36-user-email-gathering.py | 0
examples/{foundational => }/37-mem0.py | 4 -
.../38a-smart-turn-local-coreml.py | 0
.../38b-smart-turn-local.py | 0
examples/{foundational => }/39-mcp-stdio.py | 0
.../39a-mcp-streamable-http.py | 0
.../39b-mcp-streamable-http-gemini-live.py | 0
.../{foundational => }/39c-multiple-mcp.py | 0
.../{foundational => }/40-aws-nova-sonic.py | 0
.../42-interruption-config.py | 0
.../{foundational => }/43-heygen-transport.py | 0
.../43a-heygen-video-service.py | 0
.../44-voicemail-detection.py | 0
.../45-before-and-after-events.py | 0
.../{foundational => }/46-video-processing.py | 0
.../{foundational => }/47-sentry-metrics.py | 0
.../{foundational => }/48-service-switcher.py | 0
.../49a-thinking-anthropic.py | 0
.../{foundational => }/49b-thinking-google.py | 0
.../49c-thinking-functions-anthropic.py | 0
.../49d-thinking-functions-google.py | 0
.../50-ultravox-realtime.py | 0
.../50a-ultravox-realtime-text.py | 0
.../{foundational => }/51-grok-realtime.py | 0
.../{foundational => }/52-live-translation.py | 0
.../53-concurrent-llm-evaluation.py | 0
.../53-concurrent-llm-rtvi-ignored-sources.py | 0
.../54-context-summarization-openai.py | 0
.../54a-context-summarization-google.py | 0
...54b-context-summarization-manual-openai.py | 0
...54c-context-summarization-dedicated-llm.py | 0
.../55a-update-settings-deepgram-flux-stt.py | 0
...-update-settings-deepgram-sagemaker-stt.py | 0
.../55a-update-settings-deepgram-stt.py | 0
.../55b-update-settings-azure-stt.py | 0
.../55c-update-settings-google-stt.py | 0
.../55d-update-settings-assemblyai-stt.py | 0
.../55e-update-settings-gladia-stt.py | 0
...update-settings-elevenlabs-realtime-stt.py | 0
.../55g-update-settings-elevenlabs-stt.py | 0
.../55h-update-settings-speechmatics-stt.py | 0
.../55i-update-settings-whisper-api-stt.py | 0
.../55j-update-settings-sarvam-stt.py | 0
.../55k-update-settings-soniox-stt.py | 0
.../55l-update-settings-aws-transcribe-stt.py | 0
.../55m-update-settings-cartesia-stt.py | 0
.../55n-update-settings-cartesia-http-tts.py | 0
.../55n-update-settings-cartesia-tts.py | 0
...55o-update-settings-elevenlabs-http-tts.py | 0
.../55o-update-settings-elevenlabs-tts.py | 0
.../55p-update-settings-openai-tts.py | 0
.../55q-update-settings-deepgram-http-tts.py | 0
...-update-settings-deepgram-sagemaker-tts.py | 0
.../55q-update-settings-deepgram-tts.py | 0
.../55r-update-settings-azure-http-tts.py | 0
.../55r-update-settings-azure-tts.py | 0
.../55s-update-settings-google-http-tts.py | 0
.../55s-update-settings-google-stream-tts.py | 0
.../55t-update-settings-piper-http-tts.py | 0
.../55t-update-settings-piper-tts.py | 0
.../55u-update-settings-rime-http-tts.py | 0
.../55u-update-settings-rime-tts.py | 0
.../55v-update-settings-lmnt-tts.py | 0
.../55w-update-settings-fish-tts.py | 0
.../55x-update-settings-minimax-tts.py | 0
.../55y-update-settings-groq-tts.py | 0
.../55z-update-settings-hume-tts.py | 0
...55za-update-settings-neuphonic-http-tts.py | 0
.../55za-update-settings-neuphonic-tts.py | 0
.../55zb-update-settings-inworld-http-tts.py | 0
.../55zb-update-settings-inworld-tts.py | 0
.../55zc-update-settings-gemini-tts.py | 0
.../55zd-update-settings-aws-polly-tts.py | 0
.../55ze-update-settings-sarvam-http-tts.py | 0
.../55ze-update-settings-sarvam-tts.py | 0
.../55zf-update-settings-camb-tts.py | 0
.../55zg-update-settings-kokoro-tts.py | 0
.../55zh-update-settings-resembleai-tts.py | 0
.../55zi-update-settings-azure-llm.py | 0
.../55zi-update-settings-openai-llm.py | 0
...date-settings-openai-responses-http-llm.py | 0
...zi-update-settings-openai-responses-llm.py | 0
.../55zj-update-settings-anthropic-llm.py | 0
.../55zk-update-settings-google-llm.py | 0
.../55zk-update-settings-google-vertex-llm.py | 0
.../55zl-update-settings-azure-realtime.py | 0
.../55zl-update-settings-openai-realtime.py | 0
...55zm-update-settings-gemini-live-vertex.py | 0
.../55zm-update-settings-gemini-live.py | 0
.../55zn-update-settings-ultravox-realtime.py | 0
.../55zo-update-settings-grok-realtime.py | 0
.../55zp-update-settings-aws-bedrock-llm.py | 0
.../55zq-update-settings-fal-stt.py | 0
.../55zr-update-settings-gradium-stt.py | 0
.../55zs-update-settings-whisper-mlx-stt.py | 0
.../55zs-update-settings-whisper-stt.py | 0
...zt-update-settings-nvidia-segmented-stt.py | 0
.../55zt-update-settings-nvidia-stt.py | 0
...5zu-update-settings-openai-realtime-stt.py | 0
.../55zv-update-settings-asyncai-http-tts.py | 0
.../55zv-update-settings-asyncai-tts.py | 0
.../55zw-update-settings-gradium-tts.py | 0
.../55zx-update-settings-cerebras-llm.py | 0
.../55zy-update-settings-deepseek-llm.py | 0
.../55zz-update-settings-fireworks-llm.py | 0
.../55zza-update-settings-grok-llm.py | 0
.../55zzb-update-settings-groq-llm.py | 0
.../55zzc-update-settings-mistral-llm.py | 0
.../55zzd-update-settings-nvidia-llm.py | 0
.../55zze-update-settings-ollama-llm.py | 0
.../55zzf-update-settings-openrouter-llm.py | 0
.../55zzg-update-settings-perplexity-llm.py | 0
.../55zzh-update-settings-qwen-llm.py | 0
.../55zzi-update-settings-sambanova-llm.py | 0
.../55zzj-update-settings-together-llm.py | 0
...5zzk-update-settings-aws-nova-sonic-llm.py | 0
.../55zzl-update-settings-nvidia-tts.py | 0
.../55zzm-update-settings-speechmatics-tts.py | 0
.../55zzn-update-settings-groq-stt.py | 0
.../55zzp-update-settings-xtts-tts.py | 0
.../55zzq-update-settings-sarvam-llm.py | 0
.../56-lemonslice-transport.py | 0
.../57-custom-video-track.py | 2 -
examples/README.md | 150 +++++++++++++++---
examples/{foundational => }/assets/cat.jpg | Bin
examples/{foundational => }/assets/ding1.wav | Bin
examples/{foundational => }/assets/ding2.wav | Bin
.../{foundational => }/assets/moondream.png | Bin
.../assets/office-ambience-24000-mono.mp3 | Bin
.../{foundational => }/assets/rag-content.txt | 0
.../{foundational => }/assets/sc-default.png | Bin
.../{foundational => }/assets/sc-listen-1.png | Bin
.../{foundational => }/assets/sc-listen-2.png | Bin
.../{foundational => }/assets/sc-talk.png | Bin
.../{foundational => }/assets/sc-think-1.png | Bin
.../{foundational => }/assets/sc-think-2.png | Bin
.../{foundational => }/assets/sc-think-3.png | Bin
.../{foundational => }/assets/sc-think-4.png | Bin
.../{foundational => }/assets/speaking.png | Bin
.../{foundational => }/assets/waiting.png | Bin
examples/foundational/README.md | 144 -----------------
scripts/evals/run-release-evals.py | 2 +-
src/pipecat/services/settings.py | 2 +-
327 files changed, 138 insertions(+), 177 deletions(-)
rename examples/{foundational => }/01-say-one-thing-piper.py (100%)
rename examples/{foundational => }/01-say-one-thing-rime.py (100%)
rename examples/{foundational => }/01-say-one-thing.py (100%)
rename examples/{foundational => }/01a-local-audio.py (100%)
rename examples/{foundational => }/01b-livekit-audio.py (100%)
rename examples/{foundational => }/01c-nvidia-riva-tts.py (100%)
rename examples/{foundational => }/02-llm-say-one-thing.py (100%)
rename examples/{foundational => }/03-still-frame.py (100%)
rename examples/{foundational => }/03a-local-still-frame.py (100%)
rename examples/{foundational => }/03b-still-frame-imagen.py (100%)
rename examples/{foundational => }/04-transports-small-webrtc.py (100%)
rename examples/{foundational => }/04a-transports-daily.py (100%)
rename examples/{foundational => }/04b-transports-livekit.py (100%)
rename examples/{foundational => }/05-sync-speech-and-image.py (100%)
rename examples/{foundational => }/06-listen-and-respond.py (100%)
rename examples/{foundational => }/06a-image-sync.py (100%)
rename examples/{foundational => }/07-interruptible-cartesia-http.py (100%)
rename examples/{foundational => }/07-interruptible-openai-responses-http.py (100%)
rename examples/{foundational => }/07-interruptible-openai-responses.py (100%)
rename examples/{foundational => }/07-interruptible.py (100%)
rename examples/{foundational => }/07a-interruptible-speechmatics-vad.py (100%)
rename examples/{foundational => }/07a-interruptible-speechmatics.py (100%)
rename examples/{foundational => }/07b-interruptible-langchain.py (100%)
rename examples/{foundational => }/07c-interruptible-deepgram-flux-sagemaker.py (100%)
rename examples/{foundational => }/07c-interruptible-deepgram-flux.py (100%)
rename examples/{foundational => }/07c-interruptible-deepgram-http.py (100%)
rename examples/{foundational => }/07c-interruptible-deepgram-sagemaker.py (100%)
rename examples/{foundational => }/07c-interruptible-deepgram-vad.py (100%)
rename examples/{foundational => }/07c-interruptible-deepgram.py (100%)
rename examples/{foundational => }/07d-interruptible-elevenlabs-http.py (100%)
rename examples/{foundational => }/07d-interruptible-elevenlabs.py (100%)
rename examples/{foundational => }/07e-interruptible-xai.py (100%)
rename examples/{foundational => }/07f-interruptible-azure-http.py (100%)
rename examples/{foundational => }/07f-interruptible-azure.py (100%)
rename examples/{foundational => }/07g-interruptible-openai-http.py (100%)
rename examples/{foundational => }/07g-interruptible-openai.py (100%)
rename examples/{foundational => }/07i-interruptible-xtts.py (100%)
rename examples/{foundational => }/07j-interruptible-gladia-vad.py (100%)
rename examples/{foundational => }/07j-interruptible-gladia.py (100%)
rename examples/{foundational => }/07k-interruptible-lmnt.py (100%)
rename examples/{foundational => }/07l-interruptible-groq.py (100%)
rename examples/{foundational => }/07m-interruptible-aws-strands.py (100%)
rename examples/{foundational => }/07m-interruptible-aws.py (100%)
rename examples/{foundational => }/07n-interruptible-gemini-image.py (98%)
rename examples/{foundational => }/07n-interruptible-gemini.py (100%)
rename examples/{foundational => }/07n-interruptible-google-http.py (100%)
rename examples/{foundational => }/07n-interruptible-google.py (100%)
rename examples/{foundational => }/07o-interruptible-assemblyai-turn-detection.py (100%)
rename examples/{foundational => }/07o-interruptible-assemblyai.py (100%)
rename examples/{foundational => }/07p-interruptible-krisp-viva.py (100%)
rename examples/{foundational => }/07q-interruptible-rime-http.py (100%)
rename examples/{foundational => }/07q-interruptible-rime.py (100%)
rename examples/{foundational => }/07r-interruptible-nvidia.py (100%)
rename examples/{foundational => }/07s-interruptible-google-audio-in.py (100%)
rename examples/{foundational => }/07t-interruptible-fish.py (100%)
rename examples/{foundational => }/07v-interruptible-neuphonic-http.py (100%)
rename examples/{foundational => }/07v-interruptible-neuphonic.py (100%)
rename examples/{foundational => }/07w-interruptible-fal.py (100%)
rename examples/{foundational => }/07x-interruptible-local.py (100%)
rename examples/{foundational => }/07y-interruptible-minimax.py (100%)
rename examples/{foundational => }/07z-interruptible-sarvam-http.py (100%)
rename examples/{foundational => }/07z-interruptible-sarvam.py (100%)
rename examples/{foundational => }/07za-interruptible-soniox.py (100%)
rename examples/{foundational => }/07zb-interruptible-inworld-http.py (100%)
rename examples/{foundational => }/07zb-interruptible-inworld.py (100%)
rename examples/{foundational => }/07zc-interruptible-asyncai-http.py (100%)
rename examples/{foundational => }/07zc-interruptible-asyncai.py (100%)
rename examples/{foundational => }/07zd-interruptible-aicoustics.py (100%)
rename examples/{foundational => }/07ze-interruptible-hume.py (100%)
rename examples/{foundational => }/07zf-interruptible-gradium.py (100%)
rename examples/{foundational => }/07zg-interruptible-camb.py (100%)
rename examples/{foundational => }/07zi-interruptible-piper.py (100%)
rename examples/{foundational => }/07zj-interruptible-kokoro.py (100%)
rename examples/{foundational => }/07zk-interruptible-resemble.py (100%)
rename examples/{foundational => }/07zl-interruptible-smallest.py (100%)
rename examples/{foundational => }/08-custom-frame-processor.py (100%)
rename examples/{foundational => }/09-mirror.py (100%)
rename examples/{foundational => }/09a-local-mirror.py (100%)
rename examples/{foundational => }/10-wake-phrase.py (100%)
rename examples/{foundational => }/11-sound-effects.py (100%)
rename examples/{foundational => }/12-describe-image-openai-responses-http.py (100%)
rename examples/{foundational => }/12-describe-image-openai-responses.py (100%)
rename examples/{foundational => }/12-describe-image-openai.py (100%)
rename examples/{foundational => }/12a-describe-image-anthropic.py (100%)
rename examples/{foundational => }/12b-describe-image-aws.py (100%)
rename examples/{foundational => }/12c-describe-image-gemini-flash.py (100%)
rename examples/{foundational => }/12d-describe-image-moondream.py (100%)
rename examples/{foundational => }/13-whisper-transcription.py (100%)
rename examples/{foundational => }/13a-whisper-local.py (100%)
rename examples/{foundational => }/13b-deepgram-transcription.py (100%)
rename examples/{foundational => }/13c-gladia-transcription.py (100%)
rename examples/{foundational => }/13c-gladia-translation.py (100%)
rename examples/{foundational => }/13d-assemblyai-transcription.py (100%)
rename examples/{foundational => }/13e-whisper-mlx.py (100%)
rename examples/{foundational => }/13f-cartesia-transcription.py (100%)
rename examples/{foundational => }/13h-speechmatics-transcription.py (100%)
rename examples/{foundational => }/13i-soniox-transcription.py (100%)
rename examples/{foundational => }/13j-azure-transcription.py (100%)
rename examples/{foundational => }/13k-elevenlabs-transcription.py (100%)
rename examples/{foundational => }/13l-gradium-transcription.py (100%)
rename examples/{foundational => }/13m-openai-transcription.py (100%)
rename examples/{foundational => }/14-function-calling-openai-responses-http.py (100%)
rename examples/{foundational => }/14-function-calling-openai-responses.py (100%)
rename examples/{foundational => }/14-function-calling.py (100%)
rename examples/{foundational => }/14a-function-calling-anthropic.py (100%)
rename examples/{foundational => }/14b-function-calling-openai.py (100%)
rename examples/{foundational => }/14c-function-calling-together.py (100%)
rename examples/{foundational => }/14d-function-calling-anthropic-video.py (100%)
rename examples/{foundational => }/14d-function-calling-aws-video.py (100%)
rename examples/{foundational => }/14d-function-calling-gemini-flash-video.py (100%)
rename examples/{foundational => }/14d-function-calling-moondream-video.py (100%)
rename examples/{foundational => }/14d-function-calling-openai-responses-video-http.py (100%)
rename examples/{foundational => }/14d-function-calling-openai-responses-video.py (100%)
rename examples/{foundational => }/14d-function-calling-openai-video.py (100%)
rename examples/{foundational => }/14e-function-calling-google.py (100%)
rename examples/{foundational => }/14f-function-calling-groq.py (100%)
rename examples/{foundational => }/14g-function-calling-grok.py (100%)
rename examples/{foundational => }/14h-function-calling-azure.py (100%)
rename examples/{foundational => }/14i-function-calling-fireworks.py (100%)
rename examples/{foundational => }/14j-function-calling-nvidia.py (100%)
rename examples/{foundational => }/14k-function-calling-cerebras.py (100%)
rename examples/{foundational => }/14l-function-calling-deepseek.py (100%)
rename examples/{foundational => }/14m-function-calling-openrouter.py (100%)
rename examples/{foundational => }/14n-function-calling-perplexity.py (100%)
rename examples/{foundational => }/14o-function-calling-gemini-openai-format.py (100%)
rename examples/{foundational => }/14p-function-calling-gemini-vertex-ai.py (100%)
rename examples/{foundational => }/14q-function-calling-qwen.py (100%)
rename examples/{foundational => }/14r-function-calling-aws.py (100%)
rename examples/{foundational => }/14s-function-calling-sambanova.py (100%)
rename examples/{foundational => }/14t-function-calling-direct.py (100%)
rename examples/{foundational => }/14u-function-calling-ollama.py (100%)
rename examples/{foundational => }/14v-function-calling-nebius.py (100%)
rename examples/{foundational => }/14w-function-calling-mistral.py (100%)
rename examples/{foundational => }/14y-function-calling-sarvam.py (100%)
rename examples/{foundational => }/14z-function-calling-novita.py (100%)
rename examples/{foundational => }/15-switch-voices.py (100%)
rename examples/{foundational => }/15a-switch-languages.py (100%)
rename examples/{foundational => }/16-gpu-container-local-bot.py (100%)
rename examples/{foundational => }/17-detect-user-idle.py (100%)
rename examples/{foundational => }/18-gstreamer-filesrc.py (100%)
rename examples/{foundational => }/18a-gstreamer-videotestsrc.py (100%)
rename examples/{foundational => }/19-openai-realtime-beta.py (100%)
rename examples/{foundational => }/19-openai-realtime.py (100%)
rename examples/{foundational => }/19a-azure-realtime-beta.py (100%)
rename examples/{foundational => }/19a-azure-realtime.py (100%)
rename examples/{foundational => }/19b-openai-realtime-beta-text.py (100%)
rename examples/{foundational => }/19b-openai-realtime-text.py (100%)
rename examples/{foundational => }/19c-openai-realtime-live-video.py (100%)
rename examples/{foundational => }/20a-persistent-context-openai-responses-http.py (100%)
rename examples/{foundational => }/20a-persistent-context-openai-responses.py (100%)
rename examples/{foundational => }/20a-persistent-context-openai.py (100%)
rename examples/{foundational => }/20b-persistent-context-openai-realtime-beta.py (100%)
rename examples/{foundational => }/20b-persistent-context-openai-realtime.py (100%)
rename examples/{foundational => }/20c-persistent-context-anthropic.py (100%)
rename examples/{foundational => }/20d-persistent-context-gemini.py (100%)
rename examples/{foundational => }/20e-persistent-context-aws-nova-sonic.py (100%)
rename examples/{foundational => }/20f-persistent-context-grok-realtime.py (100%)
rename examples/{foundational => }/21-tavus-transport.py (100%)
rename examples/{foundational => }/21a-tavus-video-service.py (100%)
rename examples/{foundational => }/22-filter-incomplete-turns.py (100%)
rename examples/{foundational => }/23-bot-background-sound.py (100%)
rename examples/{foundational => }/24-user-mute-strategy.py (100%)
rename examples/{foundational => }/25-google-audio-in.py (100%)
rename examples/{foundational => }/26-gemini-live.py (100%)
rename examples/{foundational => }/26a-gemini-live-local-vad.py (100%)
rename examples/{foundational => }/26b-gemini-live-function-calling.py (100%)
rename examples/{foundational => }/26c-gemini-live-video.py (100%)
rename examples/{foundational => }/26e-gemini-live-google-search.py (100%)
rename examples/{foundational => }/26f-gemini-live-files-api.py (100%)
rename examples/{foundational => }/26g-gemini-live-groundingMetadata.py (100%)
rename examples/{foundational => }/26h-gemini-live-vertex-function-calling.py (100%)
rename examples/{foundational => }/26i-gemini-live-graceful-end.py (100%)
rename examples/{foundational => }/27-simli-layer.py (100%)
rename examples/{foundational => }/28-user-assistant-turns.py (100%)
rename examples/{foundational => }/29-turn-tracking-observer.py (100%)
rename examples/{foundational => }/30-observer.py (100%)
rename examples/{foundational => }/31-heartbeats.py (100%)
rename examples/{foundational => }/32-gemini-grounding-metadata.py (100%)
rename examples/{foundational => }/33-gemini-rag.py (100%)
rename examples/{foundational => }/34-audio-recording.py (100%)
rename examples/{foundational => }/35-pattern-pair-voice-switching.py (100%)
rename examples/{foundational => }/36-user-email-gathering.py (100%)
rename examples/{foundational => }/37-mem0.py (98%)
rename examples/{foundational => }/38a-smart-turn-local-coreml.py (100%)
rename examples/{foundational => }/38b-smart-turn-local.py (100%)
rename examples/{foundational => }/39-mcp-stdio.py (100%)
rename examples/{foundational => }/39a-mcp-streamable-http.py (100%)
rename examples/{foundational => }/39b-mcp-streamable-http-gemini-live.py (100%)
rename examples/{foundational => }/39c-multiple-mcp.py (100%)
rename examples/{foundational => }/40-aws-nova-sonic.py (100%)
rename examples/{foundational => }/42-interruption-config.py (100%)
rename examples/{foundational => }/43-heygen-transport.py (100%)
rename examples/{foundational => }/43a-heygen-video-service.py (100%)
rename examples/{foundational => }/44-voicemail-detection.py (100%)
rename examples/{foundational => }/45-before-and-after-events.py (100%)
rename examples/{foundational => }/46-video-processing.py (100%)
rename examples/{foundational => }/47-sentry-metrics.py (100%)
rename examples/{foundational => }/48-service-switcher.py (100%)
rename examples/{foundational => }/49a-thinking-anthropic.py (100%)
rename examples/{foundational => }/49b-thinking-google.py (100%)
rename examples/{foundational => }/49c-thinking-functions-anthropic.py (100%)
rename examples/{foundational => }/49d-thinking-functions-google.py (100%)
rename examples/{foundational => }/50-ultravox-realtime.py (100%)
rename examples/{foundational => }/50a-ultravox-realtime-text.py (100%)
rename examples/{foundational => }/51-grok-realtime.py (100%)
rename examples/{foundational => }/52-live-translation.py (100%)
rename examples/{foundational => }/53-concurrent-llm-evaluation.py (100%)
rename examples/{foundational => }/53-concurrent-llm-rtvi-ignored-sources.py (100%)
rename examples/{foundational => }/54-context-summarization-openai.py (100%)
rename examples/{foundational => }/54a-context-summarization-google.py (100%)
rename examples/{foundational => }/54b-context-summarization-manual-openai.py (100%)
rename examples/{foundational => }/54c-context-summarization-dedicated-llm.py (100%)
rename examples/{foundational => }/55a-update-settings-deepgram-flux-stt.py (100%)
rename examples/{foundational => }/55a-update-settings-deepgram-sagemaker-stt.py (100%)
rename examples/{foundational => }/55a-update-settings-deepgram-stt.py (100%)
rename examples/{foundational => }/55b-update-settings-azure-stt.py (100%)
rename examples/{foundational => }/55c-update-settings-google-stt.py (100%)
rename examples/{foundational => }/55d-update-settings-assemblyai-stt.py (100%)
rename examples/{foundational => }/55e-update-settings-gladia-stt.py (100%)
rename examples/{foundational => }/55f-update-settings-elevenlabs-realtime-stt.py (100%)
rename examples/{foundational => }/55g-update-settings-elevenlabs-stt.py (100%)
rename examples/{foundational => }/55h-update-settings-speechmatics-stt.py (100%)
rename examples/{foundational => }/55i-update-settings-whisper-api-stt.py (100%)
rename examples/{foundational => }/55j-update-settings-sarvam-stt.py (100%)
rename examples/{foundational => }/55k-update-settings-soniox-stt.py (100%)
rename examples/{foundational => }/55l-update-settings-aws-transcribe-stt.py (100%)
rename examples/{foundational => }/55m-update-settings-cartesia-stt.py (100%)
rename examples/{foundational => }/55n-update-settings-cartesia-http-tts.py (100%)
rename examples/{foundational => }/55n-update-settings-cartesia-tts.py (100%)
rename examples/{foundational => }/55o-update-settings-elevenlabs-http-tts.py (100%)
rename examples/{foundational => }/55o-update-settings-elevenlabs-tts.py (100%)
rename examples/{foundational => }/55p-update-settings-openai-tts.py (100%)
rename examples/{foundational => }/55q-update-settings-deepgram-http-tts.py (100%)
rename examples/{foundational => }/55q-update-settings-deepgram-sagemaker-tts.py (100%)
rename examples/{foundational => }/55q-update-settings-deepgram-tts.py (100%)
rename examples/{foundational => }/55r-update-settings-azure-http-tts.py (100%)
rename examples/{foundational => }/55r-update-settings-azure-tts.py (100%)
rename examples/{foundational => }/55s-update-settings-google-http-tts.py (100%)
rename examples/{foundational => }/55s-update-settings-google-stream-tts.py (100%)
rename examples/{foundational => }/55t-update-settings-piper-http-tts.py (100%)
rename examples/{foundational => }/55t-update-settings-piper-tts.py (100%)
rename examples/{foundational => }/55u-update-settings-rime-http-tts.py (100%)
rename examples/{foundational => }/55u-update-settings-rime-tts.py (100%)
rename examples/{foundational => }/55v-update-settings-lmnt-tts.py (100%)
rename examples/{foundational => }/55w-update-settings-fish-tts.py (100%)
rename examples/{foundational => }/55x-update-settings-minimax-tts.py (100%)
rename examples/{foundational => }/55y-update-settings-groq-tts.py (100%)
rename examples/{foundational => }/55z-update-settings-hume-tts.py (100%)
rename examples/{foundational => }/55za-update-settings-neuphonic-http-tts.py (100%)
rename examples/{foundational => }/55za-update-settings-neuphonic-tts.py (100%)
rename examples/{foundational => }/55zb-update-settings-inworld-http-tts.py (100%)
rename examples/{foundational => }/55zb-update-settings-inworld-tts.py (100%)
rename examples/{foundational => }/55zc-update-settings-gemini-tts.py (100%)
rename examples/{foundational => }/55zd-update-settings-aws-polly-tts.py (100%)
rename examples/{foundational => }/55ze-update-settings-sarvam-http-tts.py (100%)
rename examples/{foundational => }/55ze-update-settings-sarvam-tts.py (100%)
rename examples/{foundational => }/55zf-update-settings-camb-tts.py (100%)
rename examples/{foundational => }/55zg-update-settings-kokoro-tts.py (100%)
rename examples/{foundational => }/55zh-update-settings-resembleai-tts.py (100%)
rename examples/{foundational => }/55zi-update-settings-azure-llm.py (100%)
rename examples/{foundational => }/55zi-update-settings-openai-llm.py (100%)
rename examples/{foundational => }/55zi-update-settings-openai-responses-http-llm.py (100%)
rename examples/{foundational => }/55zi-update-settings-openai-responses-llm.py (100%)
rename examples/{foundational => }/55zj-update-settings-anthropic-llm.py (100%)
rename examples/{foundational => }/55zk-update-settings-google-llm.py (100%)
rename examples/{foundational => }/55zk-update-settings-google-vertex-llm.py (100%)
rename examples/{foundational => }/55zl-update-settings-azure-realtime.py (100%)
rename examples/{foundational => }/55zl-update-settings-openai-realtime.py (100%)
rename examples/{foundational => }/55zm-update-settings-gemini-live-vertex.py (100%)
rename examples/{foundational => }/55zm-update-settings-gemini-live.py (100%)
rename examples/{foundational => }/55zn-update-settings-ultravox-realtime.py (100%)
rename examples/{foundational => }/55zo-update-settings-grok-realtime.py (100%)
rename examples/{foundational => }/55zp-update-settings-aws-bedrock-llm.py (100%)
rename examples/{foundational => }/55zq-update-settings-fal-stt.py (100%)
rename examples/{foundational => }/55zr-update-settings-gradium-stt.py (100%)
rename examples/{foundational => }/55zs-update-settings-whisper-mlx-stt.py (100%)
rename examples/{foundational => }/55zs-update-settings-whisper-stt.py (100%)
rename examples/{foundational => }/55zt-update-settings-nvidia-segmented-stt.py (100%)
rename examples/{foundational => }/55zt-update-settings-nvidia-stt.py (100%)
rename examples/{foundational => }/55zu-update-settings-openai-realtime-stt.py (100%)
rename examples/{foundational => }/55zv-update-settings-asyncai-http-tts.py (100%)
rename examples/{foundational => }/55zv-update-settings-asyncai-tts.py (100%)
rename examples/{foundational => }/55zw-update-settings-gradium-tts.py (100%)
rename examples/{foundational => }/55zx-update-settings-cerebras-llm.py (100%)
rename examples/{foundational => }/55zy-update-settings-deepseek-llm.py (100%)
rename examples/{foundational => }/55zz-update-settings-fireworks-llm.py (100%)
rename examples/{foundational => }/55zza-update-settings-grok-llm.py (100%)
rename examples/{foundational => }/55zzb-update-settings-groq-llm.py (100%)
rename examples/{foundational => }/55zzc-update-settings-mistral-llm.py (100%)
rename examples/{foundational => }/55zzd-update-settings-nvidia-llm.py (100%)
rename examples/{foundational => }/55zze-update-settings-ollama-llm.py (100%)
rename examples/{foundational => }/55zzf-update-settings-openrouter-llm.py (100%)
rename examples/{foundational => }/55zzg-update-settings-perplexity-llm.py (100%)
rename examples/{foundational => }/55zzh-update-settings-qwen-llm.py (100%)
rename examples/{foundational => }/55zzi-update-settings-sambanova-llm.py (100%)
rename examples/{foundational => }/55zzj-update-settings-together-llm.py (100%)
rename examples/{foundational => }/55zzk-update-settings-aws-nova-sonic-llm.py (100%)
rename examples/{foundational => }/55zzl-update-settings-nvidia-tts.py (100%)
rename examples/{foundational => }/55zzm-update-settings-speechmatics-tts.py (100%)
rename examples/{foundational => }/55zzn-update-settings-groq-stt.py (100%)
rename examples/{foundational => }/55zzp-update-settings-xtts-tts.py (100%)
rename examples/{foundational => }/55zzq-update-settings-sarvam-llm.py (100%)
rename examples/{foundational => }/56-lemonslice-transport.py (100%)
rename examples/{foundational => }/57-custom-video-track.py (98%)
rename examples/{foundational => }/assets/cat.jpg (100%)
rename examples/{foundational => }/assets/ding1.wav (100%)
rename examples/{foundational => }/assets/ding2.wav (100%)
rename examples/{foundational => }/assets/moondream.png (100%)
rename examples/{foundational => }/assets/office-ambience-24000-mono.mp3 (100%)
rename examples/{foundational => }/assets/rag-content.txt (100%)
rename examples/{foundational => }/assets/sc-default.png (100%)
rename examples/{foundational => }/assets/sc-listen-1.png (100%)
rename examples/{foundational => }/assets/sc-listen-2.png (100%)
rename examples/{foundational => }/assets/sc-talk.png (100%)
rename examples/{foundational => }/assets/sc-think-1.png (100%)
rename examples/{foundational => }/assets/sc-think-2.png (100%)
rename examples/{foundational => }/assets/sc-think-3.png (100%)
rename examples/{foundational => }/assets/sc-think-4.png (100%)
rename examples/{foundational => }/assets/speaking.png (100%)
rename examples/{foundational => }/assets/waiting.png (100%)
delete mode 100644 examples/foundational/README.md
diff --git a/.claude/skills/cleanup/SKILL.md b/.claude/skills/cleanup/SKILL.md
index 91a61db39..106aac6ac 100644
--- a/.claude/skills/cleanup/SKILL.md
+++ b/.claude/skills/cleanup/SKILL.md
@@ -144,7 +144,7 @@ class InputParams(BaseModel):
#### Examples
-Validated against `examples/foundational/07-interruptible.py`:
+Validated against `examples/07-interruptible.py`:
- Proper `create_transport()` usage
- Correct pipeline structure
diff --git a/COMMUNITY_INTEGRATIONS.md b/COMMUNITY_INTEGRATIONS.md
index ab45171d7..8163e3052 100644
--- a/COMMUNITY_INTEGRATIONS.md
+++ b/COMMUNITY_INTEGRATIONS.md
@@ -23,7 +23,7 @@ Create your integration following the patterns and examples shown in the "Integr
Your repository must contain these components:
- **Source code** - Complete implementation following Pipecat patterns
-- **Foundational example** - Single file example showing basic usage (see [Pipecat examples](https://github.com/pipecat-ai/pipecat/tree/main/examples/foundational))
+- **Foundational example** - Single file example showing basic usage (see [Pipecat examples](https://github.com/pipecat-ai/pipecat/tree/main/examples))
- **README.md** - Must include:
- Introduction and explanation of your integration
- Installation instructions
diff --git a/README.md b/README.md
index 696e836b4..78b359d07 100644
--- a/README.md
+++ b/README.md
@@ -80,7 +80,7 @@ Catch new features, interviews, and how-tos on our [Pipecat TV](https://www.yout
-
+
## 🧩 Available services
@@ -142,7 +142,7 @@ You can get started with Pipecat running on your local machine, then move your a
## 🧪 Code examples
-- [Foundational](https://github.com/pipecat-ai/pipecat/tree/main/examples/foundational) — small snippets that build on each other, introducing one or two concepts at a time
+- [Foundational](https://github.com/pipecat-ai/pipecat/tree/main/examples) — small snippets that build on each other, introducing one or two concepts at a time
- [Example apps](https://github.com/pipecat-ai/pipecat-examples) — complete applications that you can use as starting points for development
## 🛠️ Contributing to the framework
diff --git a/examples/foundational/01-say-one-thing-piper.py b/examples/01-say-one-thing-piper.py
similarity index 100%
rename from examples/foundational/01-say-one-thing-piper.py
rename to examples/01-say-one-thing-piper.py
diff --git a/examples/foundational/01-say-one-thing-rime.py b/examples/01-say-one-thing-rime.py
similarity index 100%
rename from examples/foundational/01-say-one-thing-rime.py
rename to examples/01-say-one-thing-rime.py
diff --git a/examples/foundational/01-say-one-thing.py b/examples/01-say-one-thing.py
similarity index 100%
rename from examples/foundational/01-say-one-thing.py
rename to examples/01-say-one-thing.py
diff --git a/examples/foundational/01a-local-audio.py b/examples/01a-local-audio.py
similarity index 100%
rename from examples/foundational/01a-local-audio.py
rename to examples/01a-local-audio.py
diff --git a/examples/foundational/01b-livekit-audio.py b/examples/01b-livekit-audio.py
similarity index 100%
rename from examples/foundational/01b-livekit-audio.py
rename to examples/01b-livekit-audio.py
diff --git a/examples/foundational/01c-nvidia-riva-tts.py b/examples/01c-nvidia-riva-tts.py
similarity index 100%
rename from examples/foundational/01c-nvidia-riva-tts.py
rename to examples/01c-nvidia-riva-tts.py
diff --git a/examples/foundational/02-llm-say-one-thing.py b/examples/02-llm-say-one-thing.py
similarity index 100%
rename from examples/foundational/02-llm-say-one-thing.py
rename to examples/02-llm-say-one-thing.py
diff --git a/examples/foundational/03-still-frame.py b/examples/03-still-frame.py
similarity index 100%
rename from examples/foundational/03-still-frame.py
rename to examples/03-still-frame.py
diff --git a/examples/foundational/03a-local-still-frame.py b/examples/03a-local-still-frame.py
similarity index 100%
rename from examples/foundational/03a-local-still-frame.py
rename to examples/03a-local-still-frame.py
diff --git a/examples/foundational/03b-still-frame-imagen.py b/examples/03b-still-frame-imagen.py
similarity index 100%
rename from examples/foundational/03b-still-frame-imagen.py
rename to examples/03b-still-frame-imagen.py
diff --git a/examples/foundational/04-transports-small-webrtc.py b/examples/04-transports-small-webrtc.py
similarity index 100%
rename from examples/foundational/04-transports-small-webrtc.py
rename to examples/04-transports-small-webrtc.py
diff --git a/examples/foundational/04a-transports-daily.py b/examples/04a-transports-daily.py
similarity index 100%
rename from examples/foundational/04a-transports-daily.py
rename to examples/04a-transports-daily.py
diff --git a/examples/foundational/04b-transports-livekit.py b/examples/04b-transports-livekit.py
similarity index 100%
rename from examples/foundational/04b-transports-livekit.py
rename to examples/04b-transports-livekit.py
diff --git a/examples/foundational/05-sync-speech-and-image.py b/examples/05-sync-speech-and-image.py
similarity index 100%
rename from examples/foundational/05-sync-speech-and-image.py
rename to examples/05-sync-speech-and-image.py
diff --git a/examples/foundational/06-listen-and-respond.py b/examples/06-listen-and-respond.py
similarity index 100%
rename from examples/foundational/06-listen-and-respond.py
rename to examples/06-listen-and-respond.py
diff --git a/examples/foundational/06a-image-sync.py b/examples/06a-image-sync.py
similarity index 100%
rename from examples/foundational/06a-image-sync.py
rename to examples/06a-image-sync.py
diff --git a/examples/foundational/07-interruptible-cartesia-http.py b/examples/07-interruptible-cartesia-http.py
similarity index 100%
rename from examples/foundational/07-interruptible-cartesia-http.py
rename to examples/07-interruptible-cartesia-http.py
diff --git a/examples/foundational/07-interruptible-openai-responses-http.py b/examples/07-interruptible-openai-responses-http.py
similarity index 100%
rename from examples/foundational/07-interruptible-openai-responses-http.py
rename to examples/07-interruptible-openai-responses-http.py
diff --git a/examples/foundational/07-interruptible-openai-responses.py b/examples/07-interruptible-openai-responses.py
similarity index 100%
rename from examples/foundational/07-interruptible-openai-responses.py
rename to examples/07-interruptible-openai-responses.py
diff --git a/examples/foundational/07-interruptible.py b/examples/07-interruptible.py
similarity index 100%
rename from examples/foundational/07-interruptible.py
rename to examples/07-interruptible.py
diff --git a/examples/foundational/07a-interruptible-speechmatics-vad.py b/examples/07a-interruptible-speechmatics-vad.py
similarity index 100%
rename from examples/foundational/07a-interruptible-speechmatics-vad.py
rename to examples/07a-interruptible-speechmatics-vad.py
diff --git a/examples/foundational/07a-interruptible-speechmatics.py b/examples/07a-interruptible-speechmatics.py
similarity index 100%
rename from examples/foundational/07a-interruptible-speechmatics.py
rename to examples/07a-interruptible-speechmatics.py
diff --git a/examples/foundational/07b-interruptible-langchain.py b/examples/07b-interruptible-langchain.py
similarity index 100%
rename from examples/foundational/07b-interruptible-langchain.py
rename to examples/07b-interruptible-langchain.py
diff --git a/examples/foundational/07c-interruptible-deepgram-flux-sagemaker.py b/examples/07c-interruptible-deepgram-flux-sagemaker.py
similarity index 100%
rename from examples/foundational/07c-interruptible-deepgram-flux-sagemaker.py
rename to examples/07c-interruptible-deepgram-flux-sagemaker.py
diff --git a/examples/foundational/07c-interruptible-deepgram-flux.py b/examples/07c-interruptible-deepgram-flux.py
similarity index 100%
rename from examples/foundational/07c-interruptible-deepgram-flux.py
rename to examples/07c-interruptible-deepgram-flux.py
diff --git a/examples/foundational/07c-interruptible-deepgram-http.py b/examples/07c-interruptible-deepgram-http.py
similarity index 100%
rename from examples/foundational/07c-interruptible-deepgram-http.py
rename to examples/07c-interruptible-deepgram-http.py
diff --git a/examples/foundational/07c-interruptible-deepgram-sagemaker.py b/examples/07c-interruptible-deepgram-sagemaker.py
similarity index 100%
rename from examples/foundational/07c-interruptible-deepgram-sagemaker.py
rename to examples/07c-interruptible-deepgram-sagemaker.py
diff --git a/examples/foundational/07c-interruptible-deepgram-vad.py b/examples/07c-interruptible-deepgram-vad.py
similarity index 100%
rename from examples/foundational/07c-interruptible-deepgram-vad.py
rename to examples/07c-interruptible-deepgram-vad.py
diff --git a/examples/foundational/07c-interruptible-deepgram.py b/examples/07c-interruptible-deepgram.py
similarity index 100%
rename from examples/foundational/07c-interruptible-deepgram.py
rename to examples/07c-interruptible-deepgram.py
diff --git a/examples/foundational/07d-interruptible-elevenlabs-http.py b/examples/07d-interruptible-elevenlabs-http.py
similarity index 100%
rename from examples/foundational/07d-interruptible-elevenlabs-http.py
rename to examples/07d-interruptible-elevenlabs-http.py
diff --git a/examples/foundational/07d-interruptible-elevenlabs.py b/examples/07d-interruptible-elevenlabs.py
similarity index 100%
rename from examples/foundational/07d-interruptible-elevenlabs.py
rename to examples/07d-interruptible-elevenlabs.py
diff --git a/examples/foundational/07e-interruptible-xai.py b/examples/07e-interruptible-xai.py
similarity index 100%
rename from examples/foundational/07e-interruptible-xai.py
rename to examples/07e-interruptible-xai.py
diff --git a/examples/foundational/07f-interruptible-azure-http.py b/examples/07f-interruptible-azure-http.py
similarity index 100%
rename from examples/foundational/07f-interruptible-azure-http.py
rename to examples/07f-interruptible-azure-http.py
diff --git a/examples/foundational/07f-interruptible-azure.py b/examples/07f-interruptible-azure.py
similarity index 100%
rename from examples/foundational/07f-interruptible-azure.py
rename to examples/07f-interruptible-azure.py
diff --git a/examples/foundational/07g-interruptible-openai-http.py b/examples/07g-interruptible-openai-http.py
similarity index 100%
rename from examples/foundational/07g-interruptible-openai-http.py
rename to examples/07g-interruptible-openai-http.py
diff --git a/examples/foundational/07g-interruptible-openai.py b/examples/07g-interruptible-openai.py
similarity index 100%
rename from examples/foundational/07g-interruptible-openai.py
rename to examples/07g-interruptible-openai.py
diff --git a/examples/foundational/07i-interruptible-xtts.py b/examples/07i-interruptible-xtts.py
similarity index 100%
rename from examples/foundational/07i-interruptible-xtts.py
rename to examples/07i-interruptible-xtts.py
diff --git a/examples/foundational/07j-interruptible-gladia-vad.py b/examples/07j-interruptible-gladia-vad.py
similarity index 100%
rename from examples/foundational/07j-interruptible-gladia-vad.py
rename to examples/07j-interruptible-gladia-vad.py
diff --git a/examples/foundational/07j-interruptible-gladia.py b/examples/07j-interruptible-gladia.py
similarity index 100%
rename from examples/foundational/07j-interruptible-gladia.py
rename to examples/07j-interruptible-gladia.py
diff --git a/examples/foundational/07k-interruptible-lmnt.py b/examples/07k-interruptible-lmnt.py
similarity index 100%
rename from examples/foundational/07k-interruptible-lmnt.py
rename to examples/07k-interruptible-lmnt.py
diff --git a/examples/foundational/07l-interruptible-groq.py b/examples/07l-interruptible-groq.py
similarity index 100%
rename from examples/foundational/07l-interruptible-groq.py
rename to examples/07l-interruptible-groq.py
diff --git a/examples/foundational/07m-interruptible-aws-strands.py b/examples/07m-interruptible-aws-strands.py
similarity index 100%
rename from examples/foundational/07m-interruptible-aws-strands.py
rename to examples/07m-interruptible-aws-strands.py
diff --git a/examples/foundational/07m-interruptible-aws.py b/examples/07m-interruptible-aws.py
similarity index 100%
rename from examples/foundational/07m-interruptible-aws.py
rename to examples/07m-interruptible-aws.py
diff --git a/examples/foundational/07n-interruptible-gemini-image.py b/examples/07n-interruptible-gemini-image.py
similarity index 98%
rename from examples/foundational/07n-interruptible-gemini-image.py
rename to examples/07n-interruptible-gemini-image.py
index cb20178c5..80f115390 100644
--- a/examples/foundational/07n-interruptible-gemini-image.py
+++ b/examples/07n-interruptible-gemini-image.py
@@ -13,9 +13,6 @@ Features showcased:
- Gemini LLM for conversation and image generation
- Google TTS and STT
-Run with:
- python examples/foundational/07n-interruptible-gemini-image.py
-
Make sure to set your environment variables:
export GOOGLE_API_KEY=your_api_key_here
"""
diff --git a/examples/foundational/07n-interruptible-gemini.py b/examples/07n-interruptible-gemini.py
similarity index 100%
rename from examples/foundational/07n-interruptible-gemini.py
rename to examples/07n-interruptible-gemini.py
diff --git a/examples/foundational/07n-interruptible-google-http.py b/examples/07n-interruptible-google-http.py
similarity index 100%
rename from examples/foundational/07n-interruptible-google-http.py
rename to examples/07n-interruptible-google-http.py
diff --git a/examples/foundational/07n-interruptible-google.py b/examples/07n-interruptible-google.py
similarity index 100%
rename from examples/foundational/07n-interruptible-google.py
rename to examples/07n-interruptible-google.py
diff --git a/examples/foundational/07o-interruptible-assemblyai-turn-detection.py b/examples/07o-interruptible-assemblyai-turn-detection.py
similarity index 100%
rename from examples/foundational/07o-interruptible-assemblyai-turn-detection.py
rename to examples/07o-interruptible-assemblyai-turn-detection.py
diff --git a/examples/foundational/07o-interruptible-assemblyai.py b/examples/07o-interruptible-assemblyai.py
similarity index 100%
rename from examples/foundational/07o-interruptible-assemblyai.py
rename to examples/07o-interruptible-assemblyai.py
diff --git a/examples/foundational/07p-interruptible-krisp-viva.py b/examples/07p-interruptible-krisp-viva.py
similarity index 100%
rename from examples/foundational/07p-interruptible-krisp-viva.py
rename to examples/07p-interruptible-krisp-viva.py
diff --git a/examples/foundational/07q-interruptible-rime-http.py b/examples/07q-interruptible-rime-http.py
similarity index 100%
rename from examples/foundational/07q-interruptible-rime-http.py
rename to examples/07q-interruptible-rime-http.py
diff --git a/examples/foundational/07q-interruptible-rime.py b/examples/07q-interruptible-rime.py
similarity index 100%
rename from examples/foundational/07q-interruptible-rime.py
rename to examples/07q-interruptible-rime.py
diff --git a/examples/foundational/07r-interruptible-nvidia.py b/examples/07r-interruptible-nvidia.py
similarity index 100%
rename from examples/foundational/07r-interruptible-nvidia.py
rename to examples/07r-interruptible-nvidia.py
diff --git a/examples/foundational/07s-interruptible-google-audio-in.py b/examples/07s-interruptible-google-audio-in.py
similarity index 100%
rename from examples/foundational/07s-interruptible-google-audio-in.py
rename to examples/07s-interruptible-google-audio-in.py
diff --git a/examples/foundational/07t-interruptible-fish.py b/examples/07t-interruptible-fish.py
similarity index 100%
rename from examples/foundational/07t-interruptible-fish.py
rename to examples/07t-interruptible-fish.py
diff --git a/examples/foundational/07v-interruptible-neuphonic-http.py b/examples/07v-interruptible-neuphonic-http.py
similarity index 100%
rename from examples/foundational/07v-interruptible-neuphonic-http.py
rename to examples/07v-interruptible-neuphonic-http.py
diff --git a/examples/foundational/07v-interruptible-neuphonic.py b/examples/07v-interruptible-neuphonic.py
similarity index 100%
rename from examples/foundational/07v-interruptible-neuphonic.py
rename to examples/07v-interruptible-neuphonic.py
diff --git a/examples/foundational/07w-interruptible-fal.py b/examples/07w-interruptible-fal.py
similarity index 100%
rename from examples/foundational/07w-interruptible-fal.py
rename to examples/07w-interruptible-fal.py
diff --git a/examples/foundational/07x-interruptible-local.py b/examples/07x-interruptible-local.py
similarity index 100%
rename from examples/foundational/07x-interruptible-local.py
rename to examples/07x-interruptible-local.py
diff --git a/examples/foundational/07y-interruptible-minimax.py b/examples/07y-interruptible-minimax.py
similarity index 100%
rename from examples/foundational/07y-interruptible-minimax.py
rename to examples/07y-interruptible-minimax.py
diff --git a/examples/foundational/07z-interruptible-sarvam-http.py b/examples/07z-interruptible-sarvam-http.py
similarity index 100%
rename from examples/foundational/07z-interruptible-sarvam-http.py
rename to examples/07z-interruptible-sarvam-http.py
diff --git a/examples/foundational/07z-interruptible-sarvam.py b/examples/07z-interruptible-sarvam.py
similarity index 100%
rename from examples/foundational/07z-interruptible-sarvam.py
rename to examples/07z-interruptible-sarvam.py
diff --git a/examples/foundational/07za-interruptible-soniox.py b/examples/07za-interruptible-soniox.py
similarity index 100%
rename from examples/foundational/07za-interruptible-soniox.py
rename to examples/07za-interruptible-soniox.py
diff --git a/examples/foundational/07zb-interruptible-inworld-http.py b/examples/07zb-interruptible-inworld-http.py
similarity index 100%
rename from examples/foundational/07zb-interruptible-inworld-http.py
rename to examples/07zb-interruptible-inworld-http.py
diff --git a/examples/foundational/07zb-interruptible-inworld.py b/examples/07zb-interruptible-inworld.py
similarity index 100%
rename from examples/foundational/07zb-interruptible-inworld.py
rename to examples/07zb-interruptible-inworld.py
diff --git a/examples/foundational/07zc-interruptible-asyncai-http.py b/examples/07zc-interruptible-asyncai-http.py
similarity index 100%
rename from examples/foundational/07zc-interruptible-asyncai-http.py
rename to examples/07zc-interruptible-asyncai-http.py
diff --git a/examples/foundational/07zc-interruptible-asyncai.py b/examples/07zc-interruptible-asyncai.py
similarity index 100%
rename from examples/foundational/07zc-interruptible-asyncai.py
rename to examples/07zc-interruptible-asyncai.py
diff --git a/examples/foundational/07zd-interruptible-aicoustics.py b/examples/07zd-interruptible-aicoustics.py
similarity index 100%
rename from examples/foundational/07zd-interruptible-aicoustics.py
rename to examples/07zd-interruptible-aicoustics.py
diff --git a/examples/foundational/07ze-interruptible-hume.py b/examples/07ze-interruptible-hume.py
similarity index 100%
rename from examples/foundational/07ze-interruptible-hume.py
rename to examples/07ze-interruptible-hume.py
diff --git a/examples/foundational/07zf-interruptible-gradium.py b/examples/07zf-interruptible-gradium.py
similarity index 100%
rename from examples/foundational/07zf-interruptible-gradium.py
rename to examples/07zf-interruptible-gradium.py
diff --git a/examples/foundational/07zg-interruptible-camb.py b/examples/07zg-interruptible-camb.py
similarity index 100%
rename from examples/foundational/07zg-interruptible-camb.py
rename to examples/07zg-interruptible-camb.py
diff --git a/examples/foundational/07zi-interruptible-piper.py b/examples/07zi-interruptible-piper.py
similarity index 100%
rename from examples/foundational/07zi-interruptible-piper.py
rename to examples/07zi-interruptible-piper.py
diff --git a/examples/foundational/07zj-interruptible-kokoro.py b/examples/07zj-interruptible-kokoro.py
similarity index 100%
rename from examples/foundational/07zj-interruptible-kokoro.py
rename to examples/07zj-interruptible-kokoro.py
diff --git a/examples/foundational/07zk-interruptible-resemble.py b/examples/07zk-interruptible-resemble.py
similarity index 100%
rename from examples/foundational/07zk-interruptible-resemble.py
rename to examples/07zk-interruptible-resemble.py
diff --git a/examples/foundational/07zl-interruptible-smallest.py b/examples/07zl-interruptible-smallest.py
similarity index 100%
rename from examples/foundational/07zl-interruptible-smallest.py
rename to examples/07zl-interruptible-smallest.py
diff --git a/examples/foundational/08-custom-frame-processor.py b/examples/08-custom-frame-processor.py
similarity index 100%
rename from examples/foundational/08-custom-frame-processor.py
rename to examples/08-custom-frame-processor.py
diff --git a/examples/foundational/09-mirror.py b/examples/09-mirror.py
similarity index 100%
rename from examples/foundational/09-mirror.py
rename to examples/09-mirror.py
diff --git a/examples/foundational/09a-local-mirror.py b/examples/09a-local-mirror.py
similarity index 100%
rename from examples/foundational/09a-local-mirror.py
rename to examples/09a-local-mirror.py
diff --git a/examples/foundational/10-wake-phrase.py b/examples/10-wake-phrase.py
similarity index 100%
rename from examples/foundational/10-wake-phrase.py
rename to examples/10-wake-phrase.py
diff --git a/examples/foundational/11-sound-effects.py b/examples/11-sound-effects.py
similarity index 100%
rename from examples/foundational/11-sound-effects.py
rename to examples/11-sound-effects.py
diff --git a/examples/foundational/12-describe-image-openai-responses-http.py b/examples/12-describe-image-openai-responses-http.py
similarity index 100%
rename from examples/foundational/12-describe-image-openai-responses-http.py
rename to examples/12-describe-image-openai-responses-http.py
diff --git a/examples/foundational/12-describe-image-openai-responses.py b/examples/12-describe-image-openai-responses.py
similarity index 100%
rename from examples/foundational/12-describe-image-openai-responses.py
rename to examples/12-describe-image-openai-responses.py
diff --git a/examples/foundational/12-describe-image-openai.py b/examples/12-describe-image-openai.py
similarity index 100%
rename from examples/foundational/12-describe-image-openai.py
rename to examples/12-describe-image-openai.py
diff --git a/examples/foundational/12a-describe-image-anthropic.py b/examples/12a-describe-image-anthropic.py
similarity index 100%
rename from examples/foundational/12a-describe-image-anthropic.py
rename to examples/12a-describe-image-anthropic.py
diff --git a/examples/foundational/12b-describe-image-aws.py b/examples/12b-describe-image-aws.py
similarity index 100%
rename from examples/foundational/12b-describe-image-aws.py
rename to examples/12b-describe-image-aws.py
diff --git a/examples/foundational/12c-describe-image-gemini-flash.py b/examples/12c-describe-image-gemini-flash.py
similarity index 100%
rename from examples/foundational/12c-describe-image-gemini-flash.py
rename to examples/12c-describe-image-gemini-flash.py
diff --git a/examples/foundational/12d-describe-image-moondream.py b/examples/12d-describe-image-moondream.py
similarity index 100%
rename from examples/foundational/12d-describe-image-moondream.py
rename to examples/12d-describe-image-moondream.py
diff --git a/examples/foundational/13-whisper-transcription.py b/examples/13-whisper-transcription.py
similarity index 100%
rename from examples/foundational/13-whisper-transcription.py
rename to examples/13-whisper-transcription.py
diff --git a/examples/foundational/13a-whisper-local.py b/examples/13a-whisper-local.py
similarity index 100%
rename from examples/foundational/13a-whisper-local.py
rename to examples/13a-whisper-local.py
diff --git a/examples/foundational/13b-deepgram-transcription.py b/examples/13b-deepgram-transcription.py
similarity index 100%
rename from examples/foundational/13b-deepgram-transcription.py
rename to examples/13b-deepgram-transcription.py
diff --git a/examples/foundational/13c-gladia-transcription.py b/examples/13c-gladia-transcription.py
similarity index 100%
rename from examples/foundational/13c-gladia-transcription.py
rename to examples/13c-gladia-transcription.py
diff --git a/examples/foundational/13c-gladia-translation.py b/examples/13c-gladia-translation.py
similarity index 100%
rename from examples/foundational/13c-gladia-translation.py
rename to examples/13c-gladia-translation.py
diff --git a/examples/foundational/13d-assemblyai-transcription.py b/examples/13d-assemblyai-transcription.py
similarity index 100%
rename from examples/foundational/13d-assemblyai-transcription.py
rename to examples/13d-assemblyai-transcription.py
diff --git a/examples/foundational/13e-whisper-mlx.py b/examples/13e-whisper-mlx.py
similarity index 100%
rename from examples/foundational/13e-whisper-mlx.py
rename to examples/13e-whisper-mlx.py
diff --git a/examples/foundational/13f-cartesia-transcription.py b/examples/13f-cartesia-transcription.py
similarity index 100%
rename from examples/foundational/13f-cartesia-transcription.py
rename to examples/13f-cartesia-transcription.py
diff --git a/examples/foundational/13h-speechmatics-transcription.py b/examples/13h-speechmatics-transcription.py
similarity index 100%
rename from examples/foundational/13h-speechmatics-transcription.py
rename to examples/13h-speechmatics-transcription.py
diff --git a/examples/foundational/13i-soniox-transcription.py b/examples/13i-soniox-transcription.py
similarity index 100%
rename from examples/foundational/13i-soniox-transcription.py
rename to examples/13i-soniox-transcription.py
diff --git a/examples/foundational/13j-azure-transcription.py b/examples/13j-azure-transcription.py
similarity index 100%
rename from examples/foundational/13j-azure-transcription.py
rename to examples/13j-azure-transcription.py
diff --git a/examples/foundational/13k-elevenlabs-transcription.py b/examples/13k-elevenlabs-transcription.py
similarity index 100%
rename from examples/foundational/13k-elevenlabs-transcription.py
rename to examples/13k-elevenlabs-transcription.py
diff --git a/examples/foundational/13l-gradium-transcription.py b/examples/13l-gradium-transcription.py
similarity index 100%
rename from examples/foundational/13l-gradium-transcription.py
rename to examples/13l-gradium-transcription.py
diff --git a/examples/foundational/13m-openai-transcription.py b/examples/13m-openai-transcription.py
similarity index 100%
rename from examples/foundational/13m-openai-transcription.py
rename to examples/13m-openai-transcription.py
diff --git a/examples/foundational/14-function-calling-openai-responses-http.py b/examples/14-function-calling-openai-responses-http.py
similarity index 100%
rename from examples/foundational/14-function-calling-openai-responses-http.py
rename to examples/14-function-calling-openai-responses-http.py
diff --git a/examples/foundational/14-function-calling-openai-responses.py b/examples/14-function-calling-openai-responses.py
similarity index 100%
rename from examples/foundational/14-function-calling-openai-responses.py
rename to examples/14-function-calling-openai-responses.py
diff --git a/examples/foundational/14-function-calling.py b/examples/14-function-calling.py
similarity index 100%
rename from examples/foundational/14-function-calling.py
rename to examples/14-function-calling.py
diff --git a/examples/foundational/14a-function-calling-anthropic.py b/examples/14a-function-calling-anthropic.py
similarity index 100%
rename from examples/foundational/14a-function-calling-anthropic.py
rename to examples/14a-function-calling-anthropic.py
diff --git a/examples/foundational/14b-function-calling-openai.py b/examples/14b-function-calling-openai.py
similarity index 100%
rename from examples/foundational/14b-function-calling-openai.py
rename to examples/14b-function-calling-openai.py
diff --git a/examples/foundational/14c-function-calling-together.py b/examples/14c-function-calling-together.py
similarity index 100%
rename from examples/foundational/14c-function-calling-together.py
rename to examples/14c-function-calling-together.py
diff --git a/examples/foundational/14d-function-calling-anthropic-video.py b/examples/14d-function-calling-anthropic-video.py
similarity index 100%
rename from examples/foundational/14d-function-calling-anthropic-video.py
rename to examples/14d-function-calling-anthropic-video.py
diff --git a/examples/foundational/14d-function-calling-aws-video.py b/examples/14d-function-calling-aws-video.py
similarity index 100%
rename from examples/foundational/14d-function-calling-aws-video.py
rename to examples/14d-function-calling-aws-video.py
diff --git a/examples/foundational/14d-function-calling-gemini-flash-video.py b/examples/14d-function-calling-gemini-flash-video.py
similarity index 100%
rename from examples/foundational/14d-function-calling-gemini-flash-video.py
rename to examples/14d-function-calling-gemini-flash-video.py
diff --git a/examples/foundational/14d-function-calling-moondream-video.py b/examples/14d-function-calling-moondream-video.py
similarity index 100%
rename from examples/foundational/14d-function-calling-moondream-video.py
rename to examples/14d-function-calling-moondream-video.py
diff --git a/examples/foundational/14d-function-calling-openai-responses-video-http.py b/examples/14d-function-calling-openai-responses-video-http.py
similarity index 100%
rename from examples/foundational/14d-function-calling-openai-responses-video-http.py
rename to examples/14d-function-calling-openai-responses-video-http.py
diff --git a/examples/foundational/14d-function-calling-openai-responses-video.py b/examples/14d-function-calling-openai-responses-video.py
similarity index 100%
rename from examples/foundational/14d-function-calling-openai-responses-video.py
rename to examples/14d-function-calling-openai-responses-video.py
diff --git a/examples/foundational/14d-function-calling-openai-video.py b/examples/14d-function-calling-openai-video.py
similarity index 100%
rename from examples/foundational/14d-function-calling-openai-video.py
rename to examples/14d-function-calling-openai-video.py
diff --git a/examples/foundational/14e-function-calling-google.py b/examples/14e-function-calling-google.py
similarity index 100%
rename from examples/foundational/14e-function-calling-google.py
rename to examples/14e-function-calling-google.py
diff --git a/examples/foundational/14f-function-calling-groq.py b/examples/14f-function-calling-groq.py
similarity index 100%
rename from examples/foundational/14f-function-calling-groq.py
rename to examples/14f-function-calling-groq.py
diff --git a/examples/foundational/14g-function-calling-grok.py b/examples/14g-function-calling-grok.py
similarity index 100%
rename from examples/foundational/14g-function-calling-grok.py
rename to examples/14g-function-calling-grok.py
diff --git a/examples/foundational/14h-function-calling-azure.py b/examples/14h-function-calling-azure.py
similarity index 100%
rename from examples/foundational/14h-function-calling-azure.py
rename to examples/14h-function-calling-azure.py
diff --git a/examples/foundational/14i-function-calling-fireworks.py b/examples/14i-function-calling-fireworks.py
similarity index 100%
rename from examples/foundational/14i-function-calling-fireworks.py
rename to examples/14i-function-calling-fireworks.py
diff --git a/examples/foundational/14j-function-calling-nvidia.py b/examples/14j-function-calling-nvidia.py
similarity index 100%
rename from examples/foundational/14j-function-calling-nvidia.py
rename to examples/14j-function-calling-nvidia.py
diff --git a/examples/foundational/14k-function-calling-cerebras.py b/examples/14k-function-calling-cerebras.py
similarity index 100%
rename from examples/foundational/14k-function-calling-cerebras.py
rename to examples/14k-function-calling-cerebras.py
diff --git a/examples/foundational/14l-function-calling-deepseek.py b/examples/14l-function-calling-deepseek.py
similarity index 100%
rename from examples/foundational/14l-function-calling-deepseek.py
rename to examples/14l-function-calling-deepseek.py
diff --git a/examples/foundational/14m-function-calling-openrouter.py b/examples/14m-function-calling-openrouter.py
similarity index 100%
rename from examples/foundational/14m-function-calling-openrouter.py
rename to examples/14m-function-calling-openrouter.py
diff --git a/examples/foundational/14n-function-calling-perplexity.py b/examples/14n-function-calling-perplexity.py
similarity index 100%
rename from examples/foundational/14n-function-calling-perplexity.py
rename to examples/14n-function-calling-perplexity.py
diff --git a/examples/foundational/14o-function-calling-gemini-openai-format.py b/examples/14o-function-calling-gemini-openai-format.py
similarity index 100%
rename from examples/foundational/14o-function-calling-gemini-openai-format.py
rename to examples/14o-function-calling-gemini-openai-format.py
diff --git a/examples/foundational/14p-function-calling-gemini-vertex-ai.py b/examples/14p-function-calling-gemini-vertex-ai.py
similarity index 100%
rename from examples/foundational/14p-function-calling-gemini-vertex-ai.py
rename to examples/14p-function-calling-gemini-vertex-ai.py
diff --git a/examples/foundational/14q-function-calling-qwen.py b/examples/14q-function-calling-qwen.py
similarity index 100%
rename from examples/foundational/14q-function-calling-qwen.py
rename to examples/14q-function-calling-qwen.py
diff --git a/examples/foundational/14r-function-calling-aws.py b/examples/14r-function-calling-aws.py
similarity index 100%
rename from examples/foundational/14r-function-calling-aws.py
rename to examples/14r-function-calling-aws.py
diff --git a/examples/foundational/14s-function-calling-sambanova.py b/examples/14s-function-calling-sambanova.py
similarity index 100%
rename from examples/foundational/14s-function-calling-sambanova.py
rename to examples/14s-function-calling-sambanova.py
diff --git a/examples/foundational/14t-function-calling-direct.py b/examples/14t-function-calling-direct.py
similarity index 100%
rename from examples/foundational/14t-function-calling-direct.py
rename to examples/14t-function-calling-direct.py
diff --git a/examples/foundational/14u-function-calling-ollama.py b/examples/14u-function-calling-ollama.py
similarity index 100%
rename from examples/foundational/14u-function-calling-ollama.py
rename to examples/14u-function-calling-ollama.py
diff --git a/examples/foundational/14v-function-calling-nebius.py b/examples/14v-function-calling-nebius.py
similarity index 100%
rename from examples/foundational/14v-function-calling-nebius.py
rename to examples/14v-function-calling-nebius.py
diff --git a/examples/foundational/14w-function-calling-mistral.py b/examples/14w-function-calling-mistral.py
similarity index 100%
rename from examples/foundational/14w-function-calling-mistral.py
rename to examples/14w-function-calling-mistral.py
diff --git a/examples/foundational/14y-function-calling-sarvam.py b/examples/14y-function-calling-sarvam.py
similarity index 100%
rename from examples/foundational/14y-function-calling-sarvam.py
rename to examples/14y-function-calling-sarvam.py
diff --git a/examples/foundational/14z-function-calling-novita.py b/examples/14z-function-calling-novita.py
similarity index 100%
rename from examples/foundational/14z-function-calling-novita.py
rename to examples/14z-function-calling-novita.py
diff --git a/examples/foundational/15-switch-voices.py b/examples/15-switch-voices.py
similarity index 100%
rename from examples/foundational/15-switch-voices.py
rename to examples/15-switch-voices.py
diff --git a/examples/foundational/15a-switch-languages.py b/examples/15a-switch-languages.py
similarity index 100%
rename from examples/foundational/15a-switch-languages.py
rename to examples/15a-switch-languages.py
diff --git a/examples/foundational/16-gpu-container-local-bot.py b/examples/16-gpu-container-local-bot.py
similarity index 100%
rename from examples/foundational/16-gpu-container-local-bot.py
rename to examples/16-gpu-container-local-bot.py
diff --git a/examples/foundational/17-detect-user-idle.py b/examples/17-detect-user-idle.py
similarity index 100%
rename from examples/foundational/17-detect-user-idle.py
rename to examples/17-detect-user-idle.py
diff --git a/examples/foundational/18-gstreamer-filesrc.py b/examples/18-gstreamer-filesrc.py
similarity index 100%
rename from examples/foundational/18-gstreamer-filesrc.py
rename to examples/18-gstreamer-filesrc.py
diff --git a/examples/foundational/18a-gstreamer-videotestsrc.py b/examples/18a-gstreamer-videotestsrc.py
similarity index 100%
rename from examples/foundational/18a-gstreamer-videotestsrc.py
rename to examples/18a-gstreamer-videotestsrc.py
diff --git a/examples/foundational/19-openai-realtime-beta.py b/examples/19-openai-realtime-beta.py
similarity index 100%
rename from examples/foundational/19-openai-realtime-beta.py
rename to examples/19-openai-realtime-beta.py
diff --git a/examples/foundational/19-openai-realtime.py b/examples/19-openai-realtime.py
similarity index 100%
rename from examples/foundational/19-openai-realtime.py
rename to examples/19-openai-realtime.py
diff --git a/examples/foundational/19a-azure-realtime-beta.py b/examples/19a-azure-realtime-beta.py
similarity index 100%
rename from examples/foundational/19a-azure-realtime-beta.py
rename to examples/19a-azure-realtime-beta.py
diff --git a/examples/foundational/19a-azure-realtime.py b/examples/19a-azure-realtime.py
similarity index 100%
rename from examples/foundational/19a-azure-realtime.py
rename to examples/19a-azure-realtime.py
diff --git a/examples/foundational/19b-openai-realtime-beta-text.py b/examples/19b-openai-realtime-beta-text.py
similarity index 100%
rename from examples/foundational/19b-openai-realtime-beta-text.py
rename to examples/19b-openai-realtime-beta-text.py
diff --git a/examples/foundational/19b-openai-realtime-text.py b/examples/19b-openai-realtime-text.py
similarity index 100%
rename from examples/foundational/19b-openai-realtime-text.py
rename to examples/19b-openai-realtime-text.py
diff --git a/examples/foundational/19c-openai-realtime-live-video.py b/examples/19c-openai-realtime-live-video.py
similarity index 100%
rename from examples/foundational/19c-openai-realtime-live-video.py
rename to examples/19c-openai-realtime-live-video.py
diff --git a/examples/foundational/20a-persistent-context-openai-responses-http.py b/examples/20a-persistent-context-openai-responses-http.py
similarity index 100%
rename from examples/foundational/20a-persistent-context-openai-responses-http.py
rename to examples/20a-persistent-context-openai-responses-http.py
diff --git a/examples/foundational/20a-persistent-context-openai-responses.py b/examples/20a-persistent-context-openai-responses.py
similarity index 100%
rename from examples/foundational/20a-persistent-context-openai-responses.py
rename to examples/20a-persistent-context-openai-responses.py
diff --git a/examples/foundational/20a-persistent-context-openai.py b/examples/20a-persistent-context-openai.py
similarity index 100%
rename from examples/foundational/20a-persistent-context-openai.py
rename to examples/20a-persistent-context-openai.py
diff --git a/examples/foundational/20b-persistent-context-openai-realtime-beta.py b/examples/20b-persistent-context-openai-realtime-beta.py
similarity index 100%
rename from examples/foundational/20b-persistent-context-openai-realtime-beta.py
rename to examples/20b-persistent-context-openai-realtime-beta.py
diff --git a/examples/foundational/20b-persistent-context-openai-realtime.py b/examples/20b-persistent-context-openai-realtime.py
similarity index 100%
rename from examples/foundational/20b-persistent-context-openai-realtime.py
rename to examples/20b-persistent-context-openai-realtime.py
diff --git a/examples/foundational/20c-persistent-context-anthropic.py b/examples/20c-persistent-context-anthropic.py
similarity index 100%
rename from examples/foundational/20c-persistent-context-anthropic.py
rename to examples/20c-persistent-context-anthropic.py
diff --git a/examples/foundational/20d-persistent-context-gemini.py b/examples/20d-persistent-context-gemini.py
similarity index 100%
rename from examples/foundational/20d-persistent-context-gemini.py
rename to examples/20d-persistent-context-gemini.py
diff --git a/examples/foundational/20e-persistent-context-aws-nova-sonic.py b/examples/20e-persistent-context-aws-nova-sonic.py
similarity index 100%
rename from examples/foundational/20e-persistent-context-aws-nova-sonic.py
rename to examples/20e-persistent-context-aws-nova-sonic.py
diff --git a/examples/foundational/20f-persistent-context-grok-realtime.py b/examples/20f-persistent-context-grok-realtime.py
similarity index 100%
rename from examples/foundational/20f-persistent-context-grok-realtime.py
rename to examples/20f-persistent-context-grok-realtime.py
diff --git a/examples/foundational/21-tavus-transport.py b/examples/21-tavus-transport.py
similarity index 100%
rename from examples/foundational/21-tavus-transport.py
rename to examples/21-tavus-transport.py
diff --git a/examples/foundational/21a-tavus-video-service.py b/examples/21a-tavus-video-service.py
similarity index 100%
rename from examples/foundational/21a-tavus-video-service.py
rename to examples/21a-tavus-video-service.py
diff --git a/examples/foundational/22-filter-incomplete-turns.py b/examples/22-filter-incomplete-turns.py
similarity index 100%
rename from examples/foundational/22-filter-incomplete-turns.py
rename to examples/22-filter-incomplete-turns.py
diff --git a/examples/foundational/23-bot-background-sound.py b/examples/23-bot-background-sound.py
similarity index 100%
rename from examples/foundational/23-bot-background-sound.py
rename to examples/23-bot-background-sound.py
diff --git a/examples/foundational/24-user-mute-strategy.py b/examples/24-user-mute-strategy.py
similarity index 100%
rename from examples/foundational/24-user-mute-strategy.py
rename to examples/24-user-mute-strategy.py
diff --git a/examples/foundational/25-google-audio-in.py b/examples/25-google-audio-in.py
similarity index 100%
rename from examples/foundational/25-google-audio-in.py
rename to examples/25-google-audio-in.py
diff --git a/examples/foundational/26-gemini-live.py b/examples/26-gemini-live.py
similarity index 100%
rename from examples/foundational/26-gemini-live.py
rename to examples/26-gemini-live.py
diff --git a/examples/foundational/26a-gemini-live-local-vad.py b/examples/26a-gemini-live-local-vad.py
similarity index 100%
rename from examples/foundational/26a-gemini-live-local-vad.py
rename to examples/26a-gemini-live-local-vad.py
diff --git a/examples/foundational/26b-gemini-live-function-calling.py b/examples/26b-gemini-live-function-calling.py
similarity index 100%
rename from examples/foundational/26b-gemini-live-function-calling.py
rename to examples/26b-gemini-live-function-calling.py
diff --git a/examples/foundational/26c-gemini-live-video.py b/examples/26c-gemini-live-video.py
similarity index 100%
rename from examples/foundational/26c-gemini-live-video.py
rename to examples/26c-gemini-live-video.py
diff --git a/examples/foundational/26e-gemini-live-google-search.py b/examples/26e-gemini-live-google-search.py
similarity index 100%
rename from examples/foundational/26e-gemini-live-google-search.py
rename to examples/26e-gemini-live-google-search.py
diff --git a/examples/foundational/26f-gemini-live-files-api.py b/examples/26f-gemini-live-files-api.py
similarity index 100%
rename from examples/foundational/26f-gemini-live-files-api.py
rename to examples/26f-gemini-live-files-api.py
diff --git a/examples/foundational/26g-gemini-live-groundingMetadata.py b/examples/26g-gemini-live-groundingMetadata.py
similarity index 100%
rename from examples/foundational/26g-gemini-live-groundingMetadata.py
rename to examples/26g-gemini-live-groundingMetadata.py
diff --git a/examples/foundational/26h-gemini-live-vertex-function-calling.py b/examples/26h-gemini-live-vertex-function-calling.py
similarity index 100%
rename from examples/foundational/26h-gemini-live-vertex-function-calling.py
rename to examples/26h-gemini-live-vertex-function-calling.py
diff --git a/examples/foundational/26i-gemini-live-graceful-end.py b/examples/26i-gemini-live-graceful-end.py
similarity index 100%
rename from examples/foundational/26i-gemini-live-graceful-end.py
rename to examples/26i-gemini-live-graceful-end.py
diff --git a/examples/foundational/27-simli-layer.py b/examples/27-simli-layer.py
similarity index 100%
rename from examples/foundational/27-simli-layer.py
rename to examples/27-simli-layer.py
diff --git a/examples/foundational/28-user-assistant-turns.py b/examples/28-user-assistant-turns.py
similarity index 100%
rename from examples/foundational/28-user-assistant-turns.py
rename to examples/28-user-assistant-turns.py
diff --git a/examples/foundational/29-turn-tracking-observer.py b/examples/29-turn-tracking-observer.py
similarity index 100%
rename from examples/foundational/29-turn-tracking-observer.py
rename to examples/29-turn-tracking-observer.py
diff --git a/examples/foundational/30-observer.py b/examples/30-observer.py
similarity index 100%
rename from examples/foundational/30-observer.py
rename to examples/30-observer.py
diff --git a/examples/foundational/31-heartbeats.py b/examples/31-heartbeats.py
similarity index 100%
rename from examples/foundational/31-heartbeats.py
rename to examples/31-heartbeats.py
diff --git a/examples/foundational/32-gemini-grounding-metadata.py b/examples/32-gemini-grounding-metadata.py
similarity index 100%
rename from examples/foundational/32-gemini-grounding-metadata.py
rename to examples/32-gemini-grounding-metadata.py
diff --git a/examples/foundational/33-gemini-rag.py b/examples/33-gemini-rag.py
similarity index 100%
rename from examples/foundational/33-gemini-rag.py
rename to examples/33-gemini-rag.py
diff --git a/examples/foundational/34-audio-recording.py b/examples/34-audio-recording.py
similarity index 100%
rename from examples/foundational/34-audio-recording.py
rename to examples/34-audio-recording.py
diff --git a/examples/foundational/35-pattern-pair-voice-switching.py b/examples/35-pattern-pair-voice-switching.py
similarity index 100%
rename from examples/foundational/35-pattern-pair-voice-switching.py
rename to examples/35-pattern-pair-voice-switching.py
diff --git a/examples/foundational/36-user-email-gathering.py b/examples/36-user-email-gathering.py
similarity index 100%
rename from examples/foundational/36-user-email-gathering.py
rename to examples/36-user-email-gathering.py
diff --git a/examples/foundational/37-mem0.py b/examples/37-mem0.py
similarity index 98%
rename from examples/foundational/37-mem0.py
rename to examples/37-mem0.py
index a3116df24..c7c0f13bd 100644
--- a/examples/foundational/37-mem0.py
+++ b/examples/37-mem0.py
@@ -19,10 +19,6 @@ The example:
- Using Mem0 API (cloud-based memory storage)
- Using local configuration with custom LLM (self-hosted memory)
-Example usage (run from pipecat root directory):
- $ pip install "pipecat-ai[daily,openai,elevenlabs,silero,mem0]"
- $ python examples/foundational/37-mem0.py
-
Requirements:
- OpenAI API key
- ElevenLabs API key (for text-to-speech)
diff --git a/examples/foundational/38a-smart-turn-local-coreml.py b/examples/38a-smart-turn-local-coreml.py
similarity index 100%
rename from examples/foundational/38a-smart-turn-local-coreml.py
rename to examples/38a-smart-turn-local-coreml.py
diff --git a/examples/foundational/38b-smart-turn-local.py b/examples/38b-smart-turn-local.py
similarity index 100%
rename from examples/foundational/38b-smart-turn-local.py
rename to examples/38b-smart-turn-local.py
diff --git a/examples/foundational/39-mcp-stdio.py b/examples/39-mcp-stdio.py
similarity index 100%
rename from examples/foundational/39-mcp-stdio.py
rename to examples/39-mcp-stdio.py
diff --git a/examples/foundational/39a-mcp-streamable-http.py b/examples/39a-mcp-streamable-http.py
similarity index 100%
rename from examples/foundational/39a-mcp-streamable-http.py
rename to examples/39a-mcp-streamable-http.py
diff --git a/examples/foundational/39b-mcp-streamable-http-gemini-live.py b/examples/39b-mcp-streamable-http-gemini-live.py
similarity index 100%
rename from examples/foundational/39b-mcp-streamable-http-gemini-live.py
rename to examples/39b-mcp-streamable-http-gemini-live.py
diff --git a/examples/foundational/39c-multiple-mcp.py b/examples/39c-multiple-mcp.py
similarity index 100%
rename from examples/foundational/39c-multiple-mcp.py
rename to examples/39c-multiple-mcp.py
diff --git a/examples/foundational/40-aws-nova-sonic.py b/examples/40-aws-nova-sonic.py
similarity index 100%
rename from examples/foundational/40-aws-nova-sonic.py
rename to examples/40-aws-nova-sonic.py
diff --git a/examples/foundational/42-interruption-config.py b/examples/42-interruption-config.py
similarity index 100%
rename from examples/foundational/42-interruption-config.py
rename to examples/42-interruption-config.py
diff --git a/examples/foundational/43-heygen-transport.py b/examples/43-heygen-transport.py
similarity index 100%
rename from examples/foundational/43-heygen-transport.py
rename to examples/43-heygen-transport.py
diff --git a/examples/foundational/43a-heygen-video-service.py b/examples/43a-heygen-video-service.py
similarity index 100%
rename from examples/foundational/43a-heygen-video-service.py
rename to examples/43a-heygen-video-service.py
diff --git a/examples/foundational/44-voicemail-detection.py b/examples/44-voicemail-detection.py
similarity index 100%
rename from examples/foundational/44-voicemail-detection.py
rename to examples/44-voicemail-detection.py
diff --git a/examples/foundational/45-before-and-after-events.py b/examples/45-before-and-after-events.py
similarity index 100%
rename from examples/foundational/45-before-and-after-events.py
rename to examples/45-before-and-after-events.py
diff --git a/examples/foundational/46-video-processing.py b/examples/46-video-processing.py
similarity index 100%
rename from examples/foundational/46-video-processing.py
rename to examples/46-video-processing.py
diff --git a/examples/foundational/47-sentry-metrics.py b/examples/47-sentry-metrics.py
similarity index 100%
rename from examples/foundational/47-sentry-metrics.py
rename to examples/47-sentry-metrics.py
diff --git a/examples/foundational/48-service-switcher.py b/examples/48-service-switcher.py
similarity index 100%
rename from examples/foundational/48-service-switcher.py
rename to examples/48-service-switcher.py
diff --git a/examples/foundational/49a-thinking-anthropic.py b/examples/49a-thinking-anthropic.py
similarity index 100%
rename from examples/foundational/49a-thinking-anthropic.py
rename to examples/49a-thinking-anthropic.py
diff --git a/examples/foundational/49b-thinking-google.py b/examples/49b-thinking-google.py
similarity index 100%
rename from examples/foundational/49b-thinking-google.py
rename to examples/49b-thinking-google.py
diff --git a/examples/foundational/49c-thinking-functions-anthropic.py b/examples/49c-thinking-functions-anthropic.py
similarity index 100%
rename from examples/foundational/49c-thinking-functions-anthropic.py
rename to examples/49c-thinking-functions-anthropic.py
diff --git a/examples/foundational/49d-thinking-functions-google.py b/examples/49d-thinking-functions-google.py
similarity index 100%
rename from examples/foundational/49d-thinking-functions-google.py
rename to examples/49d-thinking-functions-google.py
diff --git a/examples/foundational/50-ultravox-realtime.py b/examples/50-ultravox-realtime.py
similarity index 100%
rename from examples/foundational/50-ultravox-realtime.py
rename to examples/50-ultravox-realtime.py
diff --git a/examples/foundational/50a-ultravox-realtime-text.py b/examples/50a-ultravox-realtime-text.py
similarity index 100%
rename from examples/foundational/50a-ultravox-realtime-text.py
rename to examples/50a-ultravox-realtime-text.py
diff --git a/examples/foundational/51-grok-realtime.py b/examples/51-grok-realtime.py
similarity index 100%
rename from examples/foundational/51-grok-realtime.py
rename to examples/51-grok-realtime.py
diff --git a/examples/foundational/52-live-translation.py b/examples/52-live-translation.py
similarity index 100%
rename from examples/foundational/52-live-translation.py
rename to examples/52-live-translation.py
diff --git a/examples/foundational/53-concurrent-llm-evaluation.py b/examples/53-concurrent-llm-evaluation.py
similarity index 100%
rename from examples/foundational/53-concurrent-llm-evaluation.py
rename to examples/53-concurrent-llm-evaluation.py
diff --git a/examples/foundational/53-concurrent-llm-rtvi-ignored-sources.py b/examples/53-concurrent-llm-rtvi-ignored-sources.py
similarity index 100%
rename from examples/foundational/53-concurrent-llm-rtvi-ignored-sources.py
rename to examples/53-concurrent-llm-rtvi-ignored-sources.py
diff --git a/examples/foundational/54-context-summarization-openai.py b/examples/54-context-summarization-openai.py
similarity index 100%
rename from examples/foundational/54-context-summarization-openai.py
rename to examples/54-context-summarization-openai.py
diff --git a/examples/foundational/54a-context-summarization-google.py b/examples/54a-context-summarization-google.py
similarity index 100%
rename from examples/foundational/54a-context-summarization-google.py
rename to examples/54a-context-summarization-google.py
diff --git a/examples/foundational/54b-context-summarization-manual-openai.py b/examples/54b-context-summarization-manual-openai.py
similarity index 100%
rename from examples/foundational/54b-context-summarization-manual-openai.py
rename to examples/54b-context-summarization-manual-openai.py
diff --git a/examples/foundational/54c-context-summarization-dedicated-llm.py b/examples/54c-context-summarization-dedicated-llm.py
similarity index 100%
rename from examples/foundational/54c-context-summarization-dedicated-llm.py
rename to examples/54c-context-summarization-dedicated-llm.py
diff --git a/examples/foundational/55a-update-settings-deepgram-flux-stt.py b/examples/55a-update-settings-deepgram-flux-stt.py
similarity index 100%
rename from examples/foundational/55a-update-settings-deepgram-flux-stt.py
rename to examples/55a-update-settings-deepgram-flux-stt.py
diff --git a/examples/foundational/55a-update-settings-deepgram-sagemaker-stt.py b/examples/55a-update-settings-deepgram-sagemaker-stt.py
similarity index 100%
rename from examples/foundational/55a-update-settings-deepgram-sagemaker-stt.py
rename to examples/55a-update-settings-deepgram-sagemaker-stt.py
diff --git a/examples/foundational/55a-update-settings-deepgram-stt.py b/examples/55a-update-settings-deepgram-stt.py
similarity index 100%
rename from examples/foundational/55a-update-settings-deepgram-stt.py
rename to examples/55a-update-settings-deepgram-stt.py
diff --git a/examples/foundational/55b-update-settings-azure-stt.py b/examples/55b-update-settings-azure-stt.py
similarity index 100%
rename from examples/foundational/55b-update-settings-azure-stt.py
rename to examples/55b-update-settings-azure-stt.py
diff --git a/examples/foundational/55c-update-settings-google-stt.py b/examples/55c-update-settings-google-stt.py
similarity index 100%
rename from examples/foundational/55c-update-settings-google-stt.py
rename to examples/55c-update-settings-google-stt.py
diff --git a/examples/foundational/55d-update-settings-assemblyai-stt.py b/examples/55d-update-settings-assemblyai-stt.py
similarity index 100%
rename from examples/foundational/55d-update-settings-assemblyai-stt.py
rename to examples/55d-update-settings-assemblyai-stt.py
diff --git a/examples/foundational/55e-update-settings-gladia-stt.py b/examples/55e-update-settings-gladia-stt.py
similarity index 100%
rename from examples/foundational/55e-update-settings-gladia-stt.py
rename to examples/55e-update-settings-gladia-stt.py
diff --git a/examples/foundational/55f-update-settings-elevenlabs-realtime-stt.py b/examples/55f-update-settings-elevenlabs-realtime-stt.py
similarity index 100%
rename from examples/foundational/55f-update-settings-elevenlabs-realtime-stt.py
rename to examples/55f-update-settings-elevenlabs-realtime-stt.py
diff --git a/examples/foundational/55g-update-settings-elevenlabs-stt.py b/examples/55g-update-settings-elevenlabs-stt.py
similarity index 100%
rename from examples/foundational/55g-update-settings-elevenlabs-stt.py
rename to examples/55g-update-settings-elevenlabs-stt.py
diff --git a/examples/foundational/55h-update-settings-speechmatics-stt.py b/examples/55h-update-settings-speechmatics-stt.py
similarity index 100%
rename from examples/foundational/55h-update-settings-speechmatics-stt.py
rename to examples/55h-update-settings-speechmatics-stt.py
diff --git a/examples/foundational/55i-update-settings-whisper-api-stt.py b/examples/55i-update-settings-whisper-api-stt.py
similarity index 100%
rename from examples/foundational/55i-update-settings-whisper-api-stt.py
rename to examples/55i-update-settings-whisper-api-stt.py
diff --git a/examples/foundational/55j-update-settings-sarvam-stt.py b/examples/55j-update-settings-sarvam-stt.py
similarity index 100%
rename from examples/foundational/55j-update-settings-sarvam-stt.py
rename to examples/55j-update-settings-sarvam-stt.py
diff --git a/examples/foundational/55k-update-settings-soniox-stt.py b/examples/55k-update-settings-soniox-stt.py
similarity index 100%
rename from examples/foundational/55k-update-settings-soniox-stt.py
rename to examples/55k-update-settings-soniox-stt.py
diff --git a/examples/foundational/55l-update-settings-aws-transcribe-stt.py b/examples/55l-update-settings-aws-transcribe-stt.py
similarity index 100%
rename from examples/foundational/55l-update-settings-aws-transcribe-stt.py
rename to examples/55l-update-settings-aws-transcribe-stt.py
diff --git a/examples/foundational/55m-update-settings-cartesia-stt.py b/examples/55m-update-settings-cartesia-stt.py
similarity index 100%
rename from examples/foundational/55m-update-settings-cartesia-stt.py
rename to examples/55m-update-settings-cartesia-stt.py
diff --git a/examples/foundational/55n-update-settings-cartesia-http-tts.py b/examples/55n-update-settings-cartesia-http-tts.py
similarity index 100%
rename from examples/foundational/55n-update-settings-cartesia-http-tts.py
rename to examples/55n-update-settings-cartesia-http-tts.py
diff --git a/examples/foundational/55n-update-settings-cartesia-tts.py b/examples/55n-update-settings-cartesia-tts.py
similarity index 100%
rename from examples/foundational/55n-update-settings-cartesia-tts.py
rename to examples/55n-update-settings-cartesia-tts.py
diff --git a/examples/foundational/55o-update-settings-elevenlabs-http-tts.py b/examples/55o-update-settings-elevenlabs-http-tts.py
similarity index 100%
rename from examples/foundational/55o-update-settings-elevenlabs-http-tts.py
rename to examples/55o-update-settings-elevenlabs-http-tts.py
diff --git a/examples/foundational/55o-update-settings-elevenlabs-tts.py b/examples/55o-update-settings-elevenlabs-tts.py
similarity index 100%
rename from examples/foundational/55o-update-settings-elevenlabs-tts.py
rename to examples/55o-update-settings-elevenlabs-tts.py
diff --git a/examples/foundational/55p-update-settings-openai-tts.py b/examples/55p-update-settings-openai-tts.py
similarity index 100%
rename from examples/foundational/55p-update-settings-openai-tts.py
rename to examples/55p-update-settings-openai-tts.py
diff --git a/examples/foundational/55q-update-settings-deepgram-http-tts.py b/examples/55q-update-settings-deepgram-http-tts.py
similarity index 100%
rename from examples/foundational/55q-update-settings-deepgram-http-tts.py
rename to examples/55q-update-settings-deepgram-http-tts.py
diff --git a/examples/foundational/55q-update-settings-deepgram-sagemaker-tts.py b/examples/55q-update-settings-deepgram-sagemaker-tts.py
similarity index 100%
rename from examples/foundational/55q-update-settings-deepgram-sagemaker-tts.py
rename to examples/55q-update-settings-deepgram-sagemaker-tts.py
diff --git a/examples/foundational/55q-update-settings-deepgram-tts.py b/examples/55q-update-settings-deepgram-tts.py
similarity index 100%
rename from examples/foundational/55q-update-settings-deepgram-tts.py
rename to examples/55q-update-settings-deepgram-tts.py
diff --git a/examples/foundational/55r-update-settings-azure-http-tts.py b/examples/55r-update-settings-azure-http-tts.py
similarity index 100%
rename from examples/foundational/55r-update-settings-azure-http-tts.py
rename to examples/55r-update-settings-azure-http-tts.py
diff --git a/examples/foundational/55r-update-settings-azure-tts.py b/examples/55r-update-settings-azure-tts.py
similarity index 100%
rename from examples/foundational/55r-update-settings-azure-tts.py
rename to examples/55r-update-settings-azure-tts.py
diff --git a/examples/foundational/55s-update-settings-google-http-tts.py b/examples/55s-update-settings-google-http-tts.py
similarity index 100%
rename from examples/foundational/55s-update-settings-google-http-tts.py
rename to examples/55s-update-settings-google-http-tts.py
diff --git a/examples/foundational/55s-update-settings-google-stream-tts.py b/examples/55s-update-settings-google-stream-tts.py
similarity index 100%
rename from examples/foundational/55s-update-settings-google-stream-tts.py
rename to examples/55s-update-settings-google-stream-tts.py
diff --git a/examples/foundational/55t-update-settings-piper-http-tts.py b/examples/55t-update-settings-piper-http-tts.py
similarity index 100%
rename from examples/foundational/55t-update-settings-piper-http-tts.py
rename to examples/55t-update-settings-piper-http-tts.py
diff --git a/examples/foundational/55t-update-settings-piper-tts.py b/examples/55t-update-settings-piper-tts.py
similarity index 100%
rename from examples/foundational/55t-update-settings-piper-tts.py
rename to examples/55t-update-settings-piper-tts.py
diff --git a/examples/foundational/55u-update-settings-rime-http-tts.py b/examples/55u-update-settings-rime-http-tts.py
similarity index 100%
rename from examples/foundational/55u-update-settings-rime-http-tts.py
rename to examples/55u-update-settings-rime-http-tts.py
diff --git a/examples/foundational/55u-update-settings-rime-tts.py b/examples/55u-update-settings-rime-tts.py
similarity index 100%
rename from examples/foundational/55u-update-settings-rime-tts.py
rename to examples/55u-update-settings-rime-tts.py
diff --git a/examples/foundational/55v-update-settings-lmnt-tts.py b/examples/55v-update-settings-lmnt-tts.py
similarity index 100%
rename from examples/foundational/55v-update-settings-lmnt-tts.py
rename to examples/55v-update-settings-lmnt-tts.py
diff --git a/examples/foundational/55w-update-settings-fish-tts.py b/examples/55w-update-settings-fish-tts.py
similarity index 100%
rename from examples/foundational/55w-update-settings-fish-tts.py
rename to examples/55w-update-settings-fish-tts.py
diff --git a/examples/foundational/55x-update-settings-minimax-tts.py b/examples/55x-update-settings-minimax-tts.py
similarity index 100%
rename from examples/foundational/55x-update-settings-minimax-tts.py
rename to examples/55x-update-settings-minimax-tts.py
diff --git a/examples/foundational/55y-update-settings-groq-tts.py b/examples/55y-update-settings-groq-tts.py
similarity index 100%
rename from examples/foundational/55y-update-settings-groq-tts.py
rename to examples/55y-update-settings-groq-tts.py
diff --git a/examples/foundational/55z-update-settings-hume-tts.py b/examples/55z-update-settings-hume-tts.py
similarity index 100%
rename from examples/foundational/55z-update-settings-hume-tts.py
rename to examples/55z-update-settings-hume-tts.py
diff --git a/examples/foundational/55za-update-settings-neuphonic-http-tts.py b/examples/55za-update-settings-neuphonic-http-tts.py
similarity index 100%
rename from examples/foundational/55za-update-settings-neuphonic-http-tts.py
rename to examples/55za-update-settings-neuphonic-http-tts.py
diff --git a/examples/foundational/55za-update-settings-neuphonic-tts.py b/examples/55za-update-settings-neuphonic-tts.py
similarity index 100%
rename from examples/foundational/55za-update-settings-neuphonic-tts.py
rename to examples/55za-update-settings-neuphonic-tts.py
diff --git a/examples/foundational/55zb-update-settings-inworld-http-tts.py b/examples/55zb-update-settings-inworld-http-tts.py
similarity index 100%
rename from examples/foundational/55zb-update-settings-inworld-http-tts.py
rename to examples/55zb-update-settings-inworld-http-tts.py
diff --git a/examples/foundational/55zb-update-settings-inworld-tts.py b/examples/55zb-update-settings-inworld-tts.py
similarity index 100%
rename from examples/foundational/55zb-update-settings-inworld-tts.py
rename to examples/55zb-update-settings-inworld-tts.py
diff --git a/examples/foundational/55zc-update-settings-gemini-tts.py b/examples/55zc-update-settings-gemini-tts.py
similarity index 100%
rename from examples/foundational/55zc-update-settings-gemini-tts.py
rename to examples/55zc-update-settings-gemini-tts.py
diff --git a/examples/foundational/55zd-update-settings-aws-polly-tts.py b/examples/55zd-update-settings-aws-polly-tts.py
similarity index 100%
rename from examples/foundational/55zd-update-settings-aws-polly-tts.py
rename to examples/55zd-update-settings-aws-polly-tts.py
diff --git a/examples/foundational/55ze-update-settings-sarvam-http-tts.py b/examples/55ze-update-settings-sarvam-http-tts.py
similarity index 100%
rename from examples/foundational/55ze-update-settings-sarvam-http-tts.py
rename to examples/55ze-update-settings-sarvam-http-tts.py
diff --git a/examples/foundational/55ze-update-settings-sarvam-tts.py b/examples/55ze-update-settings-sarvam-tts.py
similarity index 100%
rename from examples/foundational/55ze-update-settings-sarvam-tts.py
rename to examples/55ze-update-settings-sarvam-tts.py
diff --git a/examples/foundational/55zf-update-settings-camb-tts.py b/examples/55zf-update-settings-camb-tts.py
similarity index 100%
rename from examples/foundational/55zf-update-settings-camb-tts.py
rename to examples/55zf-update-settings-camb-tts.py
diff --git a/examples/foundational/55zg-update-settings-kokoro-tts.py b/examples/55zg-update-settings-kokoro-tts.py
similarity index 100%
rename from examples/foundational/55zg-update-settings-kokoro-tts.py
rename to examples/55zg-update-settings-kokoro-tts.py
diff --git a/examples/foundational/55zh-update-settings-resembleai-tts.py b/examples/55zh-update-settings-resembleai-tts.py
similarity index 100%
rename from examples/foundational/55zh-update-settings-resembleai-tts.py
rename to examples/55zh-update-settings-resembleai-tts.py
diff --git a/examples/foundational/55zi-update-settings-azure-llm.py b/examples/55zi-update-settings-azure-llm.py
similarity index 100%
rename from examples/foundational/55zi-update-settings-azure-llm.py
rename to examples/55zi-update-settings-azure-llm.py
diff --git a/examples/foundational/55zi-update-settings-openai-llm.py b/examples/55zi-update-settings-openai-llm.py
similarity index 100%
rename from examples/foundational/55zi-update-settings-openai-llm.py
rename to examples/55zi-update-settings-openai-llm.py
diff --git a/examples/foundational/55zi-update-settings-openai-responses-http-llm.py b/examples/55zi-update-settings-openai-responses-http-llm.py
similarity index 100%
rename from examples/foundational/55zi-update-settings-openai-responses-http-llm.py
rename to examples/55zi-update-settings-openai-responses-http-llm.py
diff --git a/examples/foundational/55zi-update-settings-openai-responses-llm.py b/examples/55zi-update-settings-openai-responses-llm.py
similarity index 100%
rename from examples/foundational/55zi-update-settings-openai-responses-llm.py
rename to examples/55zi-update-settings-openai-responses-llm.py
diff --git a/examples/foundational/55zj-update-settings-anthropic-llm.py b/examples/55zj-update-settings-anthropic-llm.py
similarity index 100%
rename from examples/foundational/55zj-update-settings-anthropic-llm.py
rename to examples/55zj-update-settings-anthropic-llm.py
diff --git a/examples/foundational/55zk-update-settings-google-llm.py b/examples/55zk-update-settings-google-llm.py
similarity index 100%
rename from examples/foundational/55zk-update-settings-google-llm.py
rename to examples/55zk-update-settings-google-llm.py
diff --git a/examples/foundational/55zk-update-settings-google-vertex-llm.py b/examples/55zk-update-settings-google-vertex-llm.py
similarity index 100%
rename from examples/foundational/55zk-update-settings-google-vertex-llm.py
rename to examples/55zk-update-settings-google-vertex-llm.py
diff --git a/examples/foundational/55zl-update-settings-azure-realtime.py b/examples/55zl-update-settings-azure-realtime.py
similarity index 100%
rename from examples/foundational/55zl-update-settings-azure-realtime.py
rename to examples/55zl-update-settings-azure-realtime.py
diff --git a/examples/foundational/55zl-update-settings-openai-realtime.py b/examples/55zl-update-settings-openai-realtime.py
similarity index 100%
rename from examples/foundational/55zl-update-settings-openai-realtime.py
rename to examples/55zl-update-settings-openai-realtime.py
diff --git a/examples/foundational/55zm-update-settings-gemini-live-vertex.py b/examples/55zm-update-settings-gemini-live-vertex.py
similarity index 100%
rename from examples/foundational/55zm-update-settings-gemini-live-vertex.py
rename to examples/55zm-update-settings-gemini-live-vertex.py
diff --git a/examples/foundational/55zm-update-settings-gemini-live.py b/examples/55zm-update-settings-gemini-live.py
similarity index 100%
rename from examples/foundational/55zm-update-settings-gemini-live.py
rename to examples/55zm-update-settings-gemini-live.py
diff --git a/examples/foundational/55zn-update-settings-ultravox-realtime.py b/examples/55zn-update-settings-ultravox-realtime.py
similarity index 100%
rename from examples/foundational/55zn-update-settings-ultravox-realtime.py
rename to examples/55zn-update-settings-ultravox-realtime.py
diff --git a/examples/foundational/55zo-update-settings-grok-realtime.py b/examples/55zo-update-settings-grok-realtime.py
similarity index 100%
rename from examples/foundational/55zo-update-settings-grok-realtime.py
rename to examples/55zo-update-settings-grok-realtime.py
diff --git a/examples/foundational/55zp-update-settings-aws-bedrock-llm.py b/examples/55zp-update-settings-aws-bedrock-llm.py
similarity index 100%
rename from examples/foundational/55zp-update-settings-aws-bedrock-llm.py
rename to examples/55zp-update-settings-aws-bedrock-llm.py
diff --git a/examples/foundational/55zq-update-settings-fal-stt.py b/examples/55zq-update-settings-fal-stt.py
similarity index 100%
rename from examples/foundational/55zq-update-settings-fal-stt.py
rename to examples/55zq-update-settings-fal-stt.py
diff --git a/examples/foundational/55zr-update-settings-gradium-stt.py b/examples/55zr-update-settings-gradium-stt.py
similarity index 100%
rename from examples/foundational/55zr-update-settings-gradium-stt.py
rename to examples/55zr-update-settings-gradium-stt.py
diff --git a/examples/foundational/55zs-update-settings-whisper-mlx-stt.py b/examples/55zs-update-settings-whisper-mlx-stt.py
similarity index 100%
rename from examples/foundational/55zs-update-settings-whisper-mlx-stt.py
rename to examples/55zs-update-settings-whisper-mlx-stt.py
diff --git a/examples/foundational/55zs-update-settings-whisper-stt.py b/examples/55zs-update-settings-whisper-stt.py
similarity index 100%
rename from examples/foundational/55zs-update-settings-whisper-stt.py
rename to examples/55zs-update-settings-whisper-stt.py
diff --git a/examples/foundational/55zt-update-settings-nvidia-segmented-stt.py b/examples/55zt-update-settings-nvidia-segmented-stt.py
similarity index 100%
rename from examples/foundational/55zt-update-settings-nvidia-segmented-stt.py
rename to examples/55zt-update-settings-nvidia-segmented-stt.py
diff --git a/examples/foundational/55zt-update-settings-nvidia-stt.py b/examples/55zt-update-settings-nvidia-stt.py
similarity index 100%
rename from examples/foundational/55zt-update-settings-nvidia-stt.py
rename to examples/55zt-update-settings-nvidia-stt.py
diff --git a/examples/foundational/55zu-update-settings-openai-realtime-stt.py b/examples/55zu-update-settings-openai-realtime-stt.py
similarity index 100%
rename from examples/foundational/55zu-update-settings-openai-realtime-stt.py
rename to examples/55zu-update-settings-openai-realtime-stt.py
diff --git a/examples/foundational/55zv-update-settings-asyncai-http-tts.py b/examples/55zv-update-settings-asyncai-http-tts.py
similarity index 100%
rename from examples/foundational/55zv-update-settings-asyncai-http-tts.py
rename to examples/55zv-update-settings-asyncai-http-tts.py
diff --git a/examples/foundational/55zv-update-settings-asyncai-tts.py b/examples/55zv-update-settings-asyncai-tts.py
similarity index 100%
rename from examples/foundational/55zv-update-settings-asyncai-tts.py
rename to examples/55zv-update-settings-asyncai-tts.py
diff --git a/examples/foundational/55zw-update-settings-gradium-tts.py b/examples/55zw-update-settings-gradium-tts.py
similarity index 100%
rename from examples/foundational/55zw-update-settings-gradium-tts.py
rename to examples/55zw-update-settings-gradium-tts.py
diff --git a/examples/foundational/55zx-update-settings-cerebras-llm.py b/examples/55zx-update-settings-cerebras-llm.py
similarity index 100%
rename from examples/foundational/55zx-update-settings-cerebras-llm.py
rename to examples/55zx-update-settings-cerebras-llm.py
diff --git a/examples/foundational/55zy-update-settings-deepseek-llm.py b/examples/55zy-update-settings-deepseek-llm.py
similarity index 100%
rename from examples/foundational/55zy-update-settings-deepseek-llm.py
rename to examples/55zy-update-settings-deepseek-llm.py
diff --git a/examples/foundational/55zz-update-settings-fireworks-llm.py b/examples/55zz-update-settings-fireworks-llm.py
similarity index 100%
rename from examples/foundational/55zz-update-settings-fireworks-llm.py
rename to examples/55zz-update-settings-fireworks-llm.py
diff --git a/examples/foundational/55zza-update-settings-grok-llm.py b/examples/55zza-update-settings-grok-llm.py
similarity index 100%
rename from examples/foundational/55zza-update-settings-grok-llm.py
rename to examples/55zza-update-settings-grok-llm.py
diff --git a/examples/foundational/55zzb-update-settings-groq-llm.py b/examples/55zzb-update-settings-groq-llm.py
similarity index 100%
rename from examples/foundational/55zzb-update-settings-groq-llm.py
rename to examples/55zzb-update-settings-groq-llm.py
diff --git a/examples/foundational/55zzc-update-settings-mistral-llm.py b/examples/55zzc-update-settings-mistral-llm.py
similarity index 100%
rename from examples/foundational/55zzc-update-settings-mistral-llm.py
rename to examples/55zzc-update-settings-mistral-llm.py
diff --git a/examples/foundational/55zzd-update-settings-nvidia-llm.py b/examples/55zzd-update-settings-nvidia-llm.py
similarity index 100%
rename from examples/foundational/55zzd-update-settings-nvidia-llm.py
rename to examples/55zzd-update-settings-nvidia-llm.py
diff --git a/examples/foundational/55zze-update-settings-ollama-llm.py b/examples/55zze-update-settings-ollama-llm.py
similarity index 100%
rename from examples/foundational/55zze-update-settings-ollama-llm.py
rename to examples/55zze-update-settings-ollama-llm.py
diff --git a/examples/foundational/55zzf-update-settings-openrouter-llm.py b/examples/55zzf-update-settings-openrouter-llm.py
similarity index 100%
rename from examples/foundational/55zzf-update-settings-openrouter-llm.py
rename to examples/55zzf-update-settings-openrouter-llm.py
diff --git a/examples/foundational/55zzg-update-settings-perplexity-llm.py b/examples/55zzg-update-settings-perplexity-llm.py
similarity index 100%
rename from examples/foundational/55zzg-update-settings-perplexity-llm.py
rename to examples/55zzg-update-settings-perplexity-llm.py
diff --git a/examples/foundational/55zzh-update-settings-qwen-llm.py b/examples/55zzh-update-settings-qwen-llm.py
similarity index 100%
rename from examples/foundational/55zzh-update-settings-qwen-llm.py
rename to examples/55zzh-update-settings-qwen-llm.py
diff --git a/examples/foundational/55zzi-update-settings-sambanova-llm.py b/examples/55zzi-update-settings-sambanova-llm.py
similarity index 100%
rename from examples/foundational/55zzi-update-settings-sambanova-llm.py
rename to examples/55zzi-update-settings-sambanova-llm.py
diff --git a/examples/foundational/55zzj-update-settings-together-llm.py b/examples/55zzj-update-settings-together-llm.py
similarity index 100%
rename from examples/foundational/55zzj-update-settings-together-llm.py
rename to examples/55zzj-update-settings-together-llm.py
diff --git a/examples/foundational/55zzk-update-settings-aws-nova-sonic-llm.py b/examples/55zzk-update-settings-aws-nova-sonic-llm.py
similarity index 100%
rename from examples/foundational/55zzk-update-settings-aws-nova-sonic-llm.py
rename to examples/55zzk-update-settings-aws-nova-sonic-llm.py
diff --git a/examples/foundational/55zzl-update-settings-nvidia-tts.py b/examples/55zzl-update-settings-nvidia-tts.py
similarity index 100%
rename from examples/foundational/55zzl-update-settings-nvidia-tts.py
rename to examples/55zzl-update-settings-nvidia-tts.py
diff --git a/examples/foundational/55zzm-update-settings-speechmatics-tts.py b/examples/55zzm-update-settings-speechmatics-tts.py
similarity index 100%
rename from examples/foundational/55zzm-update-settings-speechmatics-tts.py
rename to examples/55zzm-update-settings-speechmatics-tts.py
diff --git a/examples/foundational/55zzn-update-settings-groq-stt.py b/examples/55zzn-update-settings-groq-stt.py
similarity index 100%
rename from examples/foundational/55zzn-update-settings-groq-stt.py
rename to examples/55zzn-update-settings-groq-stt.py
diff --git a/examples/foundational/55zzp-update-settings-xtts-tts.py b/examples/55zzp-update-settings-xtts-tts.py
similarity index 100%
rename from examples/foundational/55zzp-update-settings-xtts-tts.py
rename to examples/55zzp-update-settings-xtts-tts.py
diff --git a/examples/foundational/55zzq-update-settings-sarvam-llm.py b/examples/55zzq-update-settings-sarvam-llm.py
similarity index 100%
rename from examples/foundational/55zzq-update-settings-sarvam-llm.py
rename to examples/55zzq-update-settings-sarvam-llm.py
diff --git a/examples/foundational/56-lemonslice-transport.py b/examples/56-lemonslice-transport.py
similarity index 100%
rename from examples/foundational/56-lemonslice-transport.py
rename to examples/56-lemonslice-transport.py
diff --git a/examples/foundational/57-custom-video-track.py b/examples/57-custom-video-track.py
similarity index 98%
rename from examples/foundational/57-custom-video-track.py
rename to examples/57-custom-video-track.py
index 274ab6a5e..1e6190a3b 100644
--- a/examples/foundational/57-custom-video-track.py
+++ b/examples/57-custom-video-track.py
@@ -13,8 +13,6 @@ This example outputs two video track simultaneously:
The pattern generator pushes frames to the default camera. A second processor
(BlueTintProcessor) duplicates each frame, applies a blue tint, and pushes it
to the "blue" custom video destination.
-
-Run with: python examples/foundational/56-custom-video-track.py -t daily
"""
import asyncio
diff --git a/examples/README.md b/examples/README.md
index 7eae41021..e8a0dd9bf 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -1,30 +1,144 @@
# Pipecat Examples
-This directory contains examples to help you learn how to build with Pipecat.
+This directory contains examples showing how to build voice and multimodal agents with Pipecat. Each example demonstrates specific features, progressing from basic to advanced concepts.
-## Getting Started
+## Setup
-New to Pipecat? Start here:
+1. Follow the [README](https://github.com/pipecat-ai/pipecat/blob/main/README.md#%EF%B8%8F-contributing-to-the-framework) steps to get your local environment configured.
-- **[Client/Server Web](client-server-web/)** - Learn to build web applications with Pipecat's client SDKs _(coming soon)_
-- **[Phone Bot with Twilio](phone-bot-twilio/)** - Connect your bot to a phone number _(coming soon)_
+ > **Run from root directory**: Make sure you are running the steps from the root directory.
-## Foundational Examples
+ > **Using local audio?**: The `LocalAudioTransport` requires a system dependency for `portaudio`. Install the dependency to use the transport.
-Single-file examples that introduce core Pipecat concepts one at a time. These examples:
+2. Copy the [`env.example`](../env.example) file and add API keys for services you plan to use:
-- Build on each other progressively
-- Focus on specific features or integrations
-- Are used for testing with every Pipecat release
+ ```bash
+ cp env.example .env
+ # Edit .env with your API keys
+ ```
-See the **[Foundational Examples README](foundational/)** for the complete list.
+3. Navigate to the examples directory if you aren't already there:
-## More Advanced Examples
+ ```bash
+ cd examples
+ ```
-Ready to explore complex use cases? Visit **[pipecat-examples](https://github.com/pipecat-ai/pipecat-examples)** for:
+4. Run any example:
-- Production-ready applications
-- Multi-platform client implementations
-- Telephony integrations
-- Multimodal and creative applications
-- Deployment and monitoring examples
+ ```bash
+ uv run python 01-say-one-thing.py
+ ```
+
+5. Open the web interface at http://localhost:7860/client/ and click "Connect"
+
+## Running examples with other transports
+
+Most examples support running with other transports, like Twilio or Daily.
+
+### Daily
+
+You need to create a Daily account at https://dashboard.daily.co/u/signup. Once signed up, you can create your own room from the dashboard and set the environment variables `DAILY_ROOM_URL` and `DAILY_API_KEY`. Alternatively, you can let the example create a room for you (still needs `DAILY_API_KEY` environment variable). Then, start any example with `-t daily`:
+
+```bash
+uv run 07-interruptible.py -t daily
+```
+
+### Twilio
+
+It is also possible to run the example through a Twilio phone number. You will need to setup a few things:
+
+1. Install and run [ngrok](https://ngrok.com/download).
+
+```bash
+ngrok http 7860
+```
+
+2. Configure your Twilio phone number. One way is to setup a TwiML app and set the request URL to the ngrok URL from step (1). Then, set your phone number to use the new TwiML app.
+
+Then, run the example with:
+
+```bash
+uv run 07-interruptible.py -t twilio -x NGROK_HOST_NAME
+```
+
+## Examples by Feature
+
+### Basics
+
+- **[01-say-one-thing.py](./01-say-one-thing.py)**: Most basic bot that says one phrase and exits (Transport, TTS, Event handlers)
+- **[02-llm-say-one-thing.py](./02-llm-say-one-thing.py)**: Bot generates a response with an LLM (LLM initialization)
+- **[03-still-frame.py](./03-still-frame.py)**: Displays a static image (Video transport, Image service)
+- **[04-transport.py](./04-transport.py)**: Different transport options (WebRTC, Daily, Livekit)
+
+### Conversational AI
+
+- **[07-interruptible.py](./07-interruptible.py)**: Basic voice assistant bot (STT, TTS, LLM, Interruptible speech)
+- **[10-wake-phrase.py](./10-wake-phrase.py)**: Bot activated by wake phrase (WakeCheckFilter)
+- **[22-natural-conversation.py](./22-natural-conversation.py)**: Smart turn detection (Multiple LLMs, Turn management)
+- **[38-smart-turn-fal.py](./38-smart-turn-fal.py)**: ML-based turn detection (Fal service, Local models)
+
+### Common Utilities
+
+- **[17-detect-user-idle.py](./17-detect-user-idle.py)**: Handle inactive users (UserIdleProcessor)
+- **[24-user-mute-strategy.py](./24-user-mute-strategy.py)**: Selectively mute user input (LLMUserAggregator user mute strategies)
+- **[28-transcription-processor.py](./28-transcription-processor.py)**: Record conversation text (TranscriptProcessor)
+- **[30-observer.py](./30-observer.py)**: Access frame data (Custom observers)
+- **[31-heartbeats.py](./31-heartbeats.py)**: Detect idle pipelines (Pipeline monitoring)
+- **[34-audio-recording.py](./34-audio-recording.py)**: Record conversation audio (Composite and track-level recording)
+
+### Advanced LLM Features
+
+- **[14-function-calling.py](./14-function-calling.py)**: Bot with tool usage (Function schemas, Tool registration)
+- **[20a-persistent-context-openai.py](./20a-persistent-context-openai.py)**: Persistent conversation context (Memory management)
+- **[32-gemini-grounding-metadata.py](./32-gemini-grounding-metadata.py)**: Web search capabilities (Google search integration)
+- **[33-gemini-rag.py](./33-gemini-rag.py)**: Retrieval-augmented generation (Data sources, Grounding)
+- **[37-mem0.py](./37-mem0.py)**: Long-term agent memory (Mem0 service integration)
+
+### Media Handling
+
+- **[05-sync-speech-and-images.py](./05-sync-speech-and-images.py)**: Synchronized narration with images (Custom processors, SyncParallelPipeline)
+- **[06a-image-sync.py](./06a-image-sync.py)**: Dynamic image updates while speaking (Synchronized A/V pipelines)
+- **[09-mirror.py](./09-mirror.py)**: Mirror user's audio and video (Custom frame processors)
+- **[11-sound-effects.py](./11-sound-effects.py)**: Add sounds when bot speaks (Sound playback, Event synchronization)
+- **[23-bot-background-sound.py](./23-bot-background-sound.py)**: Play background audio (SoundfileMixer)
+
+### Vision & Multimodal
+
+- **[12a-describe-video-gemini-flash.py](./12a-describe-video-gemini-flash.py)**: Bot describes user's video (Video input, Multimodal LLMs)
+- **[26c-gemini-live-video.py](./26c-gemini-live-video.py)**: Gemini with video input (Streaming video, Function calls)
+
+### Voice & Language
+
+- **[13-transcription.py](./13-transcription.py)**: Speech transcription demo (STT providers, Real-time transcription)
+- **[15-switch-voices.py](./15-switch-voices.py)**: Dynamic voice/language changing (ParallelPipelines, FunctionFilters)
+- **[25-google-audio-in.py](./25-google-audio-in.py)**: Gemini for speech recognition (Alternative transcription)
+- **[35-pattern-pair-voice-switching.py](./35-pattern-pair-voice-switching.py)**: Dynamic TTS voice switching (XML parsing, PatternPairAggregator)
+- **[36-user-email-gathering.py](./36-user-email-gathering.py)**: Spelling mode for TTS (Confirmation patterns, XML tags)
+
+### Integration Examples
+
+- **[18-gstreamer-filesrc.py](./18-gstreamer-filesrc.py)**: GStreamer video streaming (Video processing)
+- **[19-openai-realtime-beta.py](./19-openai-realtime-beta.py)**: OpenAI Speech-to-Speech (Direct S2S, Function calls)
+- **[21-tavus-layer-tavus-transport.py](./21-tavus-layer-tavus-transport.py)**: Tavus digital twin (Avatar integration)
+- **[27-simli-layer.py](./27-simli-layer.py)**: Simli avatar integration (Video synchronization)
+- **[56-lemonslice-transport.py](./56-lemonslice-transport.py)**: LemonSlice avatar integration (A/V Synced Avatar integration)
+
+### Performance & Optimization
+
+- **[16-gpu-container-local-bot.py](./16-gpu-container-local-bot.py)**: GPU-accelerated local bot (Performance measurement)
+
+## Advanced Usage
+
+### Customizing Network Settings
+
+```bash
+uv run python --host 0.0.0.0 --port 8080
+```
+
+### Troubleshooting
+
+- **No audio/video**: Check browser permissions for microphone and camera
+- **Connection errors**: Verify API keys in `.env` file
+- **Port conflicts**: Use `--port` to change the port
+
+For more examples, visit our the [pipecat-examples repository](https://github.com/pipecat-ai/pipecat-examples).
diff --git a/examples/foundational/assets/cat.jpg b/examples/assets/cat.jpg
similarity index 100%
rename from examples/foundational/assets/cat.jpg
rename to examples/assets/cat.jpg
diff --git a/examples/foundational/assets/ding1.wav b/examples/assets/ding1.wav
similarity index 100%
rename from examples/foundational/assets/ding1.wav
rename to examples/assets/ding1.wav
diff --git a/examples/foundational/assets/ding2.wav b/examples/assets/ding2.wav
similarity index 100%
rename from examples/foundational/assets/ding2.wav
rename to examples/assets/ding2.wav
diff --git a/examples/foundational/assets/moondream.png b/examples/assets/moondream.png
similarity index 100%
rename from examples/foundational/assets/moondream.png
rename to examples/assets/moondream.png
diff --git a/examples/foundational/assets/office-ambience-24000-mono.mp3 b/examples/assets/office-ambience-24000-mono.mp3
similarity index 100%
rename from examples/foundational/assets/office-ambience-24000-mono.mp3
rename to examples/assets/office-ambience-24000-mono.mp3
diff --git a/examples/foundational/assets/rag-content.txt b/examples/assets/rag-content.txt
similarity index 100%
rename from examples/foundational/assets/rag-content.txt
rename to examples/assets/rag-content.txt
diff --git a/examples/foundational/assets/sc-default.png b/examples/assets/sc-default.png
similarity index 100%
rename from examples/foundational/assets/sc-default.png
rename to examples/assets/sc-default.png
diff --git a/examples/foundational/assets/sc-listen-1.png b/examples/assets/sc-listen-1.png
similarity index 100%
rename from examples/foundational/assets/sc-listen-1.png
rename to examples/assets/sc-listen-1.png
diff --git a/examples/foundational/assets/sc-listen-2.png b/examples/assets/sc-listen-2.png
similarity index 100%
rename from examples/foundational/assets/sc-listen-2.png
rename to examples/assets/sc-listen-2.png
diff --git a/examples/foundational/assets/sc-talk.png b/examples/assets/sc-talk.png
similarity index 100%
rename from examples/foundational/assets/sc-talk.png
rename to examples/assets/sc-talk.png
diff --git a/examples/foundational/assets/sc-think-1.png b/examples/assets/sc-think-1.png
similarity index 100%
rename from examples/foundational/assets/sc-think-1.png
rename to examples/assets/sc-think-1.png
diff --git a/examples/foundational/assets/sc-think-2.png b/examples/assets/sc-think-2.png
similarity index 100%
rename from examples/foundational/assets/sc-think-2.png
rename to examples/assets/sc-think-2.png
diff --git a/examples/foundational/assets/sc-think-3.png b/examples/assets/sc-think-3.png
similarity index 100%
rename from examples/foundational/assets/sc-think-3.png
rename to examples/assets/sc-think-3.png
diff --git a/examples/foundational/assets/sc-think-4.png b/examples/assets/sc-think-4.png
similarity index 100%
rename from examples/foundational/assets/sc-think-4.png
rename to examples/assets/sc-think-4.png
diff --git a/examples/foundational/assets/speaking.png b/examples/assets/speaking.png
similarity index 100%
rename from examples/foundational/assets/speaking.png
rename to examples/assets/speaking.png
diff --git a/examples/foundational/assets/waiting.png b/examples/assets/waiting.png
similarity index 100%
rename from examples/foundational/assets/waiting.png
rename to examples/assets/waiting.png
diff --git a/examples/foundational/README.md b/examples/foundational/README.md
deleted file mode 100644
index 04e88b7e7..000000000
--- a/examples/foundational/README.md
+++ /dev/null
@@ -1,144 +0,0 @@
-# Pipecat Foundational Examples
-
-This directory contains examples showing how to build voice and multimodal agents with Pipecat. Each example demonstrates specific features, progressing from basic to advanced concepts.
-
-## Setup
-
-1. Follow the [README](https://github.com/pipecat-ai/pipecat/blob/main/README.md#%EF%B8%8F-contributing-to-the-framework) steps to get your local environment configured.
-
- > **Run from root directory**: Make sure you are running the steps from the root directory.
-
- > **Using local audio?**: The `LocalAudioTransport` requires a system dependency for `portaudio`. Install the dependency to use the transport.
-
-2. Copy the [`env.example`](../../env.example) file and add API keys for services you plan to use:
-
- ```bash
- cp env.example .env
- # Edit .env with your API keys
- ```
-
-3. Navigate to the examples directory if you aren't already there:
-
- ```bash
- cd examples/foundational
- ```
-
-4. Run any example:
-
- ```bash
- uv run python 01-say-one-thing.py
- ```
-
-5. Open the web interface at http://localhost:7860/client/ and click "Connect"
-
-## Running examples with other transports
-
-Most examples support running with other transports, like Twilio or Daily.
-
-### Daily
-
-You need to create a Daily account at https://dashboard.daily.co/u/signup. Once signed up, you can create your own room from the dashboard and set the environment variables `DAILY_ROOM_URL` and `DAILY_API_KEY`. Alternatively, you can let the example create a room for you (still needs `DAILY_API_KEY` environment variable). Then, start any example with `-t daily`:
-
-```bash
-uv run 07-interruptible.py -t daily
-```
-
-### Twilio
-
-It is also possible to run the example through a Twilio phone number. You will need to setup a few things:
-
-1. Install and run [ngrok](https://ngrok.com/download).
-
-```bash
-ngrok http 7860
-```
-
-2. Configure your Twilio phone number. One way is to setup a TwiML app and set the request URL to the ngrok URL from step (1). Then, set your phone number to use the new TwiML app.
-
-Then, run the example with:
-
-```bash
-uv run 07-interruptible.py -t twilio -x NGROK_HOST_NAME
-```
-
-## Examples by Feature
-
-### Basics
-
-- **[01-say-one-thing.py](./01-say-one-thing.py)**: Most basic bot that says one phrase and exits (Transport, TTS, Event handlers)
-- **[02-llm-say-one-thing.py](./02-llm-say-one-thing.py)**: Bot generates a response with an LLM (LLM initialization)
-- **[03-still-frame.py](./03-still-frame.py)**: Displays a static image (Video transport, Image service)
-- **[04-transport.py](./04-transport.py)**: Different transport options (WebRTC, Daily, Livekit)
-
-### Conversational AI
-
-- **[07-interruptible.py](./07-interruptible.py)**: Basic voice assistant bot (STT, TTS, LLM, Interruptible speech)
-- **[10-wake-phrase.py](./10-wake-phrase.py)**: Bot activated by wake phrase (WakeCheckFilter)
-- **[22-natural-conversation.py](./22-natural-conversation.py)**: Smart turn detection (Multiple LLMs, Turn management)
-- **[38-smart-turn-fal.py](./38-smart-turn-fal.py)**: ML-based turn detection (Fal service, Local models)
-
-### Common Utilities
-
-- **[17-detect-user-idle.py](./17-detect-user-idle.py)**: Handle inactive users (UserIdleProcessor)
-- **[24-user-mute-strategy.py](./24-user-mute-strategy.py)**: Selectively mute user input (LLMUserAggregator user mute strategies)
-- **[28-transcription-processor.py](./28-transcription-processor.py)**: Record conversation text (TranscriptProcessor)
-- **[30-observer.py](./30-observer.py)**: Access frame data (Custom observers)
-- **[31-heartbeats.py](./31-heartbeats.py)**: Detect idle pipelines (Pipeline monitoring)
-- **[34-audio-recording.py](./34-audio-recording.py)**: Record conversation audio (Composite and track-level recording)
-
-### Advanced LLM Features
-
-- **[14-function-calling.py](./14-function-calling.py)**: Bot with tool usage (Function schemas, Tool registration)
-- **[20a-persistent-context-openai.py](./20a-persistent-context-openai.py)**: Persistent conversation context (Memory management)
-- **[32-gemini-grounding-metadata.py](./32-gemini-grounding-metadata.py)**: Web search capabilities (Google search integration)
-- **[33-gemini-rag.py](./33-gemini-rag.py)**: Retrieval-augmented generation (Data sources, Grounding)
-- **[37-mem0.py](./37-mem0.py)**: Long-term agent memory (Mem0 service integration)
-
-### Media Handling
-
-- **[05-sync-speech-and-images.py](./05-sync-speech-and-images.py)**: Synchronized narration with images (Custom processors, SyncParallelPipeline)
-- **[06a-image-sync.py](./06a-image-sync.py)**: Dynamic image updates while speaking (Synchronized A/V pipelines)
-- **[09-mirror.py](./09-mirror.py)**: Mirror user's audio and video (Custom frame processors)
-- **[11-sound-effects.py](./11-sound-effects.py)**: Add sounds when bot speaks (Sound playback, Event synchronization)
-- **[23-bot-background-sound.py](./23-bot-background-sound.py)**: Play background audio (SoundfileMixer)
-
-### Vision & Multimodal
-
-- **[12a-describe-video-gemini-flash.py](./12a-describe-video-gemini-flash.py)**: Bot describes user's video (Video input, Multimodal LLMs)
-- **[26c-gemini-live-video.py](./26c-gemini-live-video.py)**: Gemini with video input (Streaming video, Function calls)
-
-### Voice & Language
-
-- **[13-transcription.py](./13-transcription.py)**: Speech transcription demo (STT providers, Real-time transcription)
-- **[15-switch-voices.py](./15-switch-voices.py)**: Dynamic voice/language changing (ParallelPipelines, FunctionFilters)
-- **[25-google-audio-in.py](./25-google-audio-in.py)**: Gemini for speech recognition (Alternative transcription)
-- **[35-pattern-pair-voice-switching.py](./35-pattern-pair-voice-switching.py)**: Dynamic TTS voice switching (XML parsing, PatternPairAggregator)
-- **[36-user-email-gathering.py](./36-user-email-gathering.py)**: Spelling mode for TTS (Confirmation patterns, XML tags)
-
-### Integration Examples
-
-- **[18-gstreamer-filesrc.py](./18-gstreamer-filesrc.py)**: GStreamer video streaming (Video processing)
-- **[19-openai-realtime-beta.py](./19-openai-realtime-beta.py)**: OpenAI Speech-to-Speech (Direct S2S, Function calls)
-- **[21-tavus-layer-tavus-transport.py](./21-tavus-layer-tavus-transport.py)**: Tavus digital twin (Avatar integration)
-- **[27-simli-layer.py](./27-simli-layer.py)**: Simli avatar integration (Video synchronization)
-- **[56-lemonslice-transport.py](./56-lemonslice-transport.py)**: LemonSlice avatar integration (A/V Synced Avatar integration)
-
-### Performance & Optimization
-
-- **[16-gpu-container-local-bot.py](./16-gpu-container-local-bot.py)**: GPU-accelerated local bot (Performance measurement)
-
-## Advanced Usage
-
-### Customizing Network Settings
-
-```bash
-uv run python --host 0.0.0.0 --port 8080
-```
-
-### Troubleshooting
-
-- **No audio/video**: Check browser permissions for microphone and camera
-- **Connection errors**: Verify API keys in `.env` file
-- **Port conflicts**: Use `--port` to change the port
-
-For more examples, visit our the [pipecat-examples repository](https://github.com/pipecat-ai/pipecat-examples).
diff --git a/scripts/evals/run-release-evals.py b/scripts/evals/run-release-evals.py
index ea59988ac..92e872ac2 100644
--- a/scripts/evals/run-release-evals.py
+++ b/scripts/evals/run-release-evals.py
@@ -22,7 +22,7 @@ SCRIPT_DIR = Path(__file__).resolve().parent
ASSETS_DIR = SCRIPT_DIR / "assets"
-FOUNDATIONAL_DIR = SCRIPT_DIR.parent.parent / "examples" / "foundational"
+FOUNDATIONAL_DIR = SCRIPT_DIR.parent.parent / "examples"
EVAL_SIMPLE_MATH = EvalConfig(
prompt="A simple math addition.",
diff --git a/src/pipecat/services/settings.py b/src/pipecat/services/settings.py
index a0bf3cd58..54465b041 100644
--- a/src/pipecat/services/settings.py
+++ b/src/pipecat/services/settings.py
@@ -365,7 +365,7 @@ class LLMSettings(ServiceSettings):
seed: Random seed for reproducibility.
filter_incomplete_user_turns: Enable LLM-based turn completion detection
to suppress bot responses when the user was cut off mid-thought.
- See ``examples/foundational/22-filter-incomplete-turns.py`` and
+ See ``examples/22-filter-incomplete-turns.py`` and
``UserTurnCompletionLLMServiceMixin``.
user_turn_completion_config: Configuration for turn completion behavior
when ``filter_incomplete_user_turns`` is enabled. Controls timeouts
From e719cbbe6d3a6ceb759078d3f9c1600b5210b2de Mon Sep 17 00:00:00 2001
From: Mark Backman
Date: Tue, 31 Mar 2026 09:58:05 -0400
Subject: [PATCH 08/19] Reorganize examples into topic-based subfolders
Move 304 examples from a flat numbered directory into 14 descriptive
subfolders: getting-started, services (speech + function-calling),
transcription, vision, realtime, persistent-context,
context-summarization, update-settings (stt/tts/llm), turn-management,
thinking-and-mcp, transports, video-avatar, video-processing, and
features.
Strip numbered prefixes from filenames (e.g. 07c-interruptible-deepgram.py
becomes services/speech/deepgram.py) since the folder context makes them
redundant. Keep numbered prefixes only in getting-started/ where ordering
matters.
Update eval script paths and README to match the new structure.
---
README.md | 2 +-
examples/01-say-one-thing-piper.py | 71 ----
examples/01-say-one-thing-rime.py | 72 ----
examples/01b-livekit-audio.py | 64 ----
examples/01c-nvidia-riva-tts.py | 64 ----
examples/03-still-frame.py | 84 -----
examples/README.md | 113 +++---
.../dedicated-llm.py} | 0
.../google.py} | 0
.../manual-openai.py} | 0
.../openai.py} | 0
.../audio-recording.py} | 0
.../before-and-after-events.py} | 0
.../bot-background-sound.py} | 0
.../concurrent-llm-evaluation.py} | 0
.../concurrent-llm-rtvi-ignored-sources.py} | 0
.../custom-frame-processor.py} | 0
.../gemini-grounding-metadata.py} | 0
.../gemini-rag.py} | 0
.../gpu-container-local-bot.py} | 0
.../heartbeats.py} | 0
.../live-translation.py} | 0
examples/{37-mem0.py => features/mem0.py} | 0
.../{30-observer.py => features/observer.py} | 0
.../pattern-pair-voice-switching.py} | 0
.../sentry-metrics.py} | 0
.../service-switcher.py} | 0
.../sound-effects.py} | 0
.../switch-languages.py} | 0
.../switch-voices.py} | 0
.../user-email-gathering.py} | 0
.../voicemail-detection.py} | 0
.../wake-phrase.py} | 0
.../{ => getting-started}/01-say-one-thing.py | 0
.../{ => getting-started}/01a-local-audio.py | 0
.../02-llm-say-one-thing.py | 0
.../03-still-frame.py} | 0
.../03a-local-still-frame.py | 0
.../04-sync-speech-and-image.py} | 0
.../05-speaking-state.py} | 4 +-
.../06-voice-agent.py} | 0
.../06a-voice-agent-local.py} | 0
.../07-function-calling.py} | 0
.../anthropic.py} | 0
.../aws-nova-sonic.py} | 0
.../gemini.py} | 0
.../grok-realtime.py} | 0
.../openai-realtime-beta.py} | 0
.../openai-realtime.py} | 0
.../openai-responses-http.py} | 0
.../openai-responses.py} | 0
.../openai.py} | 0
.../aws-nova-sonic.py} | 0
.../azure-beta.py} | 0
.../azure.py} | 0
.../gemini-live-files-api.py} | 0
.../gemini-live-function-calling.py} | 0
.../gemini-live-google-search.py} | 0
.../gemini-live-graceful-end.py} | 0
.../gemini-live-grounding-metadata.py} | 0
.../gemini-live-local-vad.py} | 0
.../gemini-live-vertex-function-calling.py} | 0
.../gemini-live-video.py} | 0
.../gemini-live.py} | 0
.../{51-grok-realtime.py => realtime/grok.py} | 0
.../openai-beta-text.py} | 0
.../openai-beta.py} | 0
.../openai-live-video.py} | 0
.../openai-text.py} | 0
.../openai.py} | 0
.../ultravox-text.py} | 0
.../ultravox.py} | 0
.../function-calling/anthropic-video.py} | 0
.../function-calling/anthropic.py} | 0
.../function-calling/aws-video.py} | 0
.../function-calling/aws.py} | 0
.../function-calling/azure.py} | 0
.../function-calling/cerebras.py} | 0
.../function-calling/deepseek.py} | 0
.../function-calling/direct.py} | 0
.../function-calling/fireworks.py} | 0
.../function-calling/gemini-openai-format.py} | 0
.../function-calling/google-vertex-ai.py} | 0
.../function-calling/google-video.py} | 0
.../function-calling/google.py} | 0
.../function-calling/grok.py} | 0
.../function-calling/groq.py} | 0
.../function-calling/mistral.py} | 0
.../function-calling/moondream-video.py} | 0
.../function-calling/nebius.py} | 0
.../function-calling/novita.py} | 0
.../function-calling/nvidia.py} | 0
.../function-calling/ollama.py} | 0
.../openai-responses-http.py} | 0
.../openai-responses-video-http.py} | 0
.../openai-responses-video.py} | 0
.../function-calling/openai-responses.py} | 0
.../function-calling/openai-video.py} | 0
.../function-calling/openai.py} | 0
.../function-calling/openrouter.py} | 0
.../function-calling/perplexity.py} | 0
.../function-calling/qwen.py} | 0
.../function-calling/sambanova.py} | 0
.../function-calling/sarvam.py} | 0
.../function-calling/together.py} | 0
.../speech/aicoustics.py} | 0
.../speech/assemblyai-turn-detection.py} | 0
.../speech/assemblyai.py} | 0
.../speech/asyncai-http.py} | 0
.../speech/asyncai.py} | 0
.../speech/aws-strands.py} | 0
.../speech/aws.py} | 0
.../speech/azure-http.py} | 0
.../speech/azure.py} | 0
.../speech/camb.py} | 0
.../speech/cartesia-http.py} | 0
.../speech/cartesia.py} | 50 +--
.../speech/deepgram-flux-sagemaker.py} | 0
.../speech/deepgram-flux.py} | 0
.../speech/deepgram-http.py} | 0
.../speech/deepgram-sagemaker.py} | 0
.../speech/deepgram-vad.py} | 0
.../speech/deepgram.py} | 0
.../speech/elevenlabs-http.py} | 0
.../speech/elevenlabs.py} | 0
.../speech/fal.py} | 0
.../speech/fish.py} | 0
.../speech/gladia-vad.py} | 0
.../speech/gladia.py} | 0
.../speech/google-audio-in.py} | 0
.../speech/google-gemini-tts.py} | 0
.../speech/google-http.py} | 0
.../speech/google-image.py} | 0
.../speech/google.py} | 0
.../speech/gradium.py} | 0
.../speech/groq.py} | 0
.../speech/hume.py} | 0
.../speech/inworld-http.py} | 0
.../speech/inworld.py} | 0
.../speech/kokoro.py} | 0
.../speech/krisp-viva.py} | 0
.../speech/langchain.py} | 0
.../speech/lmnt.py} | 0
.../speech/minimax.py} | 0
.../speech/neuphonic-http.py} | 0
.../speech/neuphonic.py} | 0
.../speech/nvidia.py} | 0
.../speech/openai-http.py} | 0
.../speech/openai-responses-http.py} | 0
.../speech/openai-responses.py} | 0
.../speech/openai.py} | 0
.../speech/piper.py} | 0
.../speech/resemble.py} | 0
.../speech/rime-http.py} | 0
.../speech/rime.py} | 0
.../speech/sarvam-http.py} | 0
.../speech/sarvam.py} | 0
.../speech/smallest.py} | 0
.../speech/soniox.py} | 0
.../speech/speechmatics-vad.py} | 0
.../speech/speechmatics.py} | 0
.../speech/xai.py} | 0
.../speech/xtts.py} | 0
.../mcp-stdio.py} | 0
.../mcp-streamable-http-gemini-live.py} | 0
.../mcp-streamable-http.py} | 0
.../multiple-mcp.py} | 0
.../thinking-anthropic.py} | 0
.../thinking-functions-anthropic.py} | 0
.../thinking-functions-google.py} | 0
.../thinking-google.py} | 0
.../assemblyai.py} | 0
.../azure.py} | 0
.../cartesia.py} | 0
.../deepgram.py} | 0
.../elevenlabs.py} | 0
.../gladia-transcription.py} | 0
.../gladia-translation.py} | 0
.../google-llm.py} | 0
.../gradium.py} | 0
.../openai.py} | 0
.../soniox.py} | 0
.../speechmatics.py} | 0
.../whisper-local.py} | 0
.../whisper-mlx.py} | 0
.../whisper.py} | 0
.../daily.py} | 0
.../livekit.py} | 0
.../small-webrtc.py} | 0
.../detect-user-idle.py} | 0
.../filter-incomplete-turns.py} | 0
.../interruption-config.py} | 0
.../smart-turn-local-coreml.py} | 0
.../smart-turn-local.py} | 0
.../turn-tracking-observer.py} | 0
.../user-assistant-turns.py} | 0
.../user-mute-strategy.py} | 0
.../llm/anthropic.py} | 0
.../llm/aws-bedrock.py} | 0
.../llm/aws-nova-sonic.py} | 0
.../llm/azure-realtime.py} | 0
.../llm/azure.py} | 0
.../llm/cerebras.py} | 0
.../llm/deepseek.py} | 0
.../llm/fireworks.py} | 0
.../llm/gemini-live-vertex.py} | 0
.../llm/gemini-live.py} | 0
.../llm/google-vertex.py} | 0
.../llm/google.py} | 0
.../llm/grok-realtime.py} | 0
.../llm/grok.py} | 0
.../llm/groq.py} | 0
.../llm/mistral.py} | 0
.../llm/nvidia.py} | 0
.../llm/ollama.py} | 0
.../llm/openai-realtime.py} | 0
.../llm/openai-responses-http.py} | 0
.../llm/openai-responses.py} | 0
.../llm/openai.py} | 0
.../llm/openrouter.py} | 0
.../llm/perplexity.py} | 0
.../llm/qwen.py} | 0
.../llm/sambanova.py} | 0
.../llm/sarvam.py} | 0
.../llm/together.py} | 0
.../llm/ultravox-realtime.py} | 0
.../stt/assemblyai.py} | 0
.../stt/aws-transcribe.py} | 0
.../stt/azure.py} | 0
.../stt/cartesia.py} | 0
.../stt/deepgram-flux.py} | 0
.../stt/deepgram-sagemaker.py} | 0
.../stt/deepgram.py} | 0
.../stt/elevenlabs-realtime.py} | 0
.../stt/elevenlabs.py} | 0
.../stt/fal.py} | 0
.../stt/gladia.py} | 0
.../stt/google.py} | 0
.../stt/gradium.py} | 0
.../stt/groq.py} | 0
.../stt/nvidia-segmented.py} | 0
.../stt/nvidia.py} | 0
.../stt/openai-realtime.py} | 0
.../stt/sarvam.py} | 0
.../stt/soniox.py} | 0
.../stt/speechmatics.py} | 0
.../stt/whisper-api.py} | 0
.../stt/whisper-mlx.py} | 0
.../stt/whisper.py} | 0
.../tts/asyncai-http.py} | 0
.../tts/asyncai.py} | 0
.../tts/aws-polly.py} | 0
.../tts/azure-http.py} | 0
.../tts/azure.py} | 0
.../tts/camb.py} | 0
.../tts/cartesia-http.py} | 0
.../tts/cartesia.py} | 0
.../tts/deepgram-http.py} | 0
.../tts/deepgram-sagemaker.py} | 0
.../tts/deepgram.py} | 0
.../tts/elevenlabs-http.py} | 0
.../tts/elevenlabs.py} | 0
.../tts/fish.py} | 0
.../tts/gemini.py} | 0
.../tts/google-http.py} | 0
.../tts/google-stream.py} | 0
.../tts/gradium.py} | 0
.../tts/groq.py} | 0
.../tts/hume.py} | 0
.../tts/inworld-http.py} | 0
.../tts/inworld.py} | 0
.../tts/kokoro.py} | 0
.../tts/lmnt.py} | 0
.../tts/minimax.py} | 0
.../tts/neuphonic-http.py} | 0
.../tts/neuphonic.py} | 0
.../tts/nvidia.py} | 0
.../tts/openai.py} | 0
.../tts/piper-http.py} | 0
.../tts/piper.py} | 0
.../tts/resembleai.py} | 0
.../tts/rime-http.py} | 0
.../tts/rime.py} | 0
.../tts/sarvam-http.py} | 0
.../tts/sarvam.py} | 0
.../tts/speechmatics.py} | 0
.../tts/xtts.py} | 0
.../heygen-transport.py} | 0
.../heygen-video-service.py} | 0
.../lemonslice-transport.py} | 0
.../simli-layer.py} | 0
.../tavus-transport.py} | 0
.../tavus-video-service.py} | 0
.../custom-video-track.py} | 0
.../gstreamer-filesrc.py} | 0
.../gstreamer-videotestsrc.py} | 0
.../local-mirror.py} | 0
.../mirror.py} | 0
.../video-processing.py} | 0
.../anthropic.py} | 0
.../aws.py} | 0
.../gemini-flash.py} | 0
.../moondream.py} | 0
.../openai-responses-http.py} | 0
.../openai-responses.py} | 0
.../openai.py} | 0
scripts/evals/run-release-evals.py | 327 ++++++++----------
307 files changed, 210 insertions(+), 641 deletions(-)
delete mode 100644 examples/01-say-one-thing-piper.py
delete mode 100644 examples/01-say-one-thing-rime.py
delete mode 100644 examples/01b-livekit-audio.py
delete mode 100644 examples/01c-nvidia-riva-tts.py
delete mode 100644 examples/03-still-frame.py
rename examples/{54c-context-summarization-dedicated-llm.py => context-summarization/dedicated-llm.py} (100%)
rename examples/{54a-context-summarization-google.py => context-summarization/google.py} (100%)
rename examples/{54b-context-summarization-manual-openai.py => context-summarization/manual-openai.py} (100%)
rename examples/{54-context-summarization-openai.py => context-summarization/openai.py} (100%)
rename examples/{34-audio-recording.py => features/audio-recording.py} (100%)
rename examples/{45-before-and-after-events.py => features/before-and-after-events.py} (100%)
rename examples/{23-bot-background-sound.py => features/bot-background-sound.py} (100%)
rename examples/{53-concurrent-llm-evaluation.py => features/concurrent-llm-evaluation.py} (100%)
rename examples/{53-concurrent-llm-rtvi-ignored-sources.py => features/concurrent-llm-rtvi-ignored-sources.py} (100%)
rename examples/{08-custom-frame-processor.py => features/custom-frame-processor.py} (100%)
rename examples/{32-gemini-grounding-metadata.py => features/gemini-grounding-metadata.py} (100%)
rename examples/{33-gemini-rag.py => features/gemini-rag.py} (100%)
rename examples/{16-gpu-container-local-bot.py => features/gpu-container-local-bot.py} (100%)
rename examples/{31-heartbeats.py => features/heartbeats.py} (100%)
rename examples/{52-live-translation.py => features/live-translation.py} (100%)
rename examples/{37-mem0.py => features/mem0.py} (100%)
rename examples/{30-observer.py => features/observer.py} (100%)
rename examples/{35-pattern-pair-voice-switching.py => features/pattern-pair-voice-switching.py} (100%)
rename examples/{47-sentry-metrics.py => features/sentry-metrics.py} (100%)
rename examples/{48-service-switcher.py => features/service-switcher.py} (100%)
rename examples/{11-sound-effects.py => features/sound-effects.py} (100%)
rename examples/{15a-switch-languages.py => features/switch-languages.py} (100%)
rename examples/{15-switch-voices.py => features/switch-voices.py} (100%)
rename examples/{36-user-email-gathering.py => features/user-email-gathering.py} (100%)
rename examples/{44-voicemail-detection.py => features/voicemail-detection.py} (100%)
rename examples/{10-wake-phrase.py => features/wake-phrase.py} (100%)
rename examples/{ => getting-started}/01-say-one-thing.py (100%)
rename examples/{ => getting-started}/01a-local-audio.py (100%)
rename examples/{ => getting-started}/02-llm-say-one-thing.py (100%)
rename examples/{03b-still-frame-imagen.py => getting-started/03-still-frame.py} (100%)
rename examples/{ => getting-started}/03a-local-still-frame.py (100%)
rename examples/{05-sync-speech-and-image.py => getting-started/04-sync-speech-and-image.py} (100%)
rename examples/{06a-image-sync.py => getting-started/05-speaking-state.py} (97%)
rename examples/{07-interruptible.py => getting-started/06-voice-agent.py} (100%)
rename examples/{07x-interruptible-local.py => getting-started/06a-voice-agent-local.py} (100%)
rename examples/{14-function-calling.py => getting-started/07-function-calling.py} (100%)
rename examples/{20c-persistent-context-anthropic.py => persistent-context/anthropic.py} (100%)
rename examples/{20e-persistent-context-aws-nova-sonic.py => persistent-context/aws-nova-sonic.py} (100%)
rename examples/{20d-persistent-context-gemini.py => persistent-context/gemini.py} (100%)
rename examples/{20f-persistent-context-grok-realtime.py => persistent-context/grok-realtime.py} (100%)
rename examples/{20b-persistent-context-openai-realtime-beta.py => persistent-context/openai-realtime-beta.py} (100%)
rename examples/{20b-persistent-context-openai-realtime.py => persistent-context/openai-realtime.py} (100%)
rename examples/{20a-persistent-context-openai-responses-http.py => persistent-context/openai-responses-http.py} (100%)
rename examples/{20a-persistent-context-openai-responses.py => persistent-context/openai-responses.py} (100%)
rename examples/{20a-persistent-context-openai.py => persistent-context/openai.py} (100%)
rename examples/{40-aws-nova-sonic.py => realtime/aws-nova-sonic.py} (100%)
rename examples/{19a-azure-realtime-beta.py => realtime/azure-beta.py} (100%)
rename examples/{19a-azure-realtime.py => realtime/azure.py} (100%)
rename examples/{26f-gemini-live-files-api.py => realtime/gemini-live-files-api.py} (100%)
rename examples/{26b-gemini-live-function-calling.py => realtime/gemini-live-function-calling.py} (100%)
rename examples/{26e-gemini-live-google-search.py => realtime/gemini-live-google-search.py} (100%)
rename examples/{26i-gemini-live-graceful-end.py => realtime/gemini-live-graceful-end.py} (100%)
rename examples/{26g-gemini-live-groundingMetadata.py => realtime/gemini-live-grounding-metadata.py} (100%)
rename examples/{26a-gemini-live-local-vad.py => realtime/gemini-live-local-vad.py} (100%)
rename examples/{26h-gemini-live-vertex-function-calling.py => realtime/gemini-live-vertex-function-calling.py} (100%)
rename examples/{26c-gemini-live-video.py => realtime/gemini-live-video.py} (100%)
rename examples/{26-gemini-live.py => realtime/gemini-live.py} (100%)
rename examples/{51-grok-realtime.py => realtime/grok.py} (100%)
rename examples/{19b-openai-realtime-beta-text.py => realtime/openai-beta-text.py} (100%)
rename examples/{19-openai-realtime-beta.py => realtime/openai-beta.py} (100%)
rename examples/{19c-openai-realtime-live-video.py => realtime/openai-live-video.py} (100%)
rename examples/{19b-openai-realtime-text.py => realtime/openai-text.py} (100%)
rename examples/{19-openai-realtime.py => realtime/openai.py} (100%)
rename examples/{50a-ultravox-realtime-text.py => realtime/ultravox-text.py} (100%)
rename examples/{50-ultravox-realtime.py => realtime/ultravox.py} (100%)
rename examples/{14d-function-calling-anthropic-video.py => services/function-calling/anthropic-video.py} (100%)
rename examples/{14a-function-calling-anthropic.py => services/function-calling/anthropic.py} (100%)
rename examples/{14d-function-calling-aws-video.py => services/function-calling/aws-video.py} (100%)
rename examples/{14r-function-calling-aws.py => services/function-calling/aws.py} (100%)
rename examples/{14h-function-calling-azure.py => services/function-calling/azure.py} (100%)
rename examples/{14k-function-calling-cerebras.py => services/function-calling/cerebras.py} (100%)
rename examples/{14l-function-calling-deepseek.py => services/function-calling/deepseek.py} (100%)
rename examples/{14t-function-calling-direct.py => services/function-calling/direct.py} (100%)
rename examples/{14i-function-calling-fireworks.py => services/function-calling/fireworks.py} (100%)
rename examples/{14o-function-calling-gemini-openai-format.py => services/function-calling/gemini-openai-format.py} (100%)
rename examples/{14p-function-calling-gemini-vertex-ai.py => services/function-calling/google-vertex-ai.py} (100%)
rename examples/{14d-function-calling-gemini-flash-video.py => services/function-calling/google-video.py} (100%)
rename examples/{14e-function-calling-google.py => services/function-calling/google.py} (100%)
rename examples/{14g-function-calling-grok.py => services/function-calling/grok.py} (100%)
rename examples/{14f-function-calling-groq.py => services/function-calling/groq.py} (100%)
rename examples/{14w-function-calling-mistral.py => services/function-calling/mistral.py} (100%)
rename examples/{14d-function-calling-moondream-video.py => services/function-calling/moondream-video.py} (100%)
rename examples/{14v-function-calling-nebius.py => services/function-calling/nebius.py} (100%)
rename examples/{14z-function-calling-novita.py => services/function-calling/novita.py} (100%)
rename examples/{14j-function-calling-nvidia.py => services/function-calling/nvidia.py} (100%)
rename examples/{14u-function-calling-ollama.py => services/function-calling/ollama.py} (100%)
rename examples/{14-function-calling-openai-responses-http.py => services/function-calling/openai-responses-http.py} (100%)
rename examples/{14d-function-calling-openai-responses-video-http.py => services/function-calling/openai-responses-video-http.py} (100%)
rename examples/{14d-function-calling-openai-responses-video.py => services/function-calling/openai-responses-video.py} (100%)
rename examples/{14-function-calling-openai-responses.py => services/function-calling/openai-responses.py} (100%)
rename examples/{14d-function-calling-openai-video.py => services/function-calling/openai-video.py} (100%)
rename examples/{14b-function-calling-openai.py => services/function-calling/openai.py} (100%)
rename examples/{14m-function-calling-openrouter.py => services/function-calling/openrouter.py} (100%)
rename examples/{14n-function-calling-perplexity.py => services/function-calling/perplexity.py} (100%)
rename examples/{14q-function-calling-qwen.py => services/function-calling/qwen.py} (100%)
rename examples/{14s-function-calling-sambanova.py => services/function-calling/sambanova.py} (100%)
rename examples/{14y-function-calling-sarvam.py => services/function-calling/sarvam.py} (100%)
rename examples/{14c-function-calling-together.py => services/function-calling/together.py} (100%)
rename examples/{07zd-interruptible-aicoustics.py => services/speech/aicoustics.py} (100%)
rename examples/{07o-interruptible-assemblyai-turn-detection.py => services/speech/assemblyai-turn-detection.py} (100%)
rename examples/{07o-interruptible-assemblyai.py => services/speech/assemblyai.py} (100%)
rename examples/{07zc-interruptible-asyncai-http.py => services/speech/asyncai-http.py} (100%)
rename examples/{07zc-interruptible-asyncai.py => services/speech/asyncai.py} (100%)
rename examples/{07m-interruptible-aws-strands.py => services/speech/aws-strands.py} (100%)
rename examples/{07m-interruptible-aws.py => services/speech/aws.py} (100%)
rename examples/{07f-interruptible-azure-http.py => services/speech/azure-http.py} (100%)
rename examples/{07f-interruptible-azure.py => services/speech/azure.py} (100%)
rename examples/{07zg-interruptible-camb.py => services/speech/camb.py} (100%)
rename examples/{07-interruptible-cartesia-http.py => services/speech/cartesia-http.py} (100%)
rename examples/{06-listen-and-respond.py => services/speech/cartesia.py} (69%)
rename examples/{07c-interruptible-deepgram-flux-sagemaker.py => services/speech/deepgram-flux-sagemaker.py} (100%)
rename examples/{07c-interruptible-deepgram-flux.py => services/speech/deepgram-flux.py} (100%)
rename examples/{07c-interruptible-deepgram-http.py => services/speech/deepgram-http.py} (100%)
rename examples/{07c-interruptible-deepgram-sagemaker.py => services/speech/deepgram-sagemaker.py} (100%)
rename examples/{07c-interruptible-deepgram-vad.py => services/speech/deepgram-vad.py} (100%)
rename examples/{07c-interruptible-deepgram.py => services/speech/deepgram.py} (100%)
rename examples/{07d-interruptible-elevenlabs-http.py => services/speech/elevenlabs-http.py} (100%)
rename examples/{07d-interruptible-elevenlabs.py => services/speech/elevenlabs.py} (100%)
rename examples/{07w-interruptible-fal.py => services/speech/fal.py} (100%)
rename examples/{07t-interruptible-fish.py => services/speech/fish.py} (100%)
rename examples/{07j-interruptible-gladia-vad.py => services/speech/gladia-vad.py} (100%)
rename examples/{07j-interruptible-gladia.py => services/speech/gladia.py} (100%)
rename examples/{07s-interruptible-google-audio-in.py => services/speech/google-audio-in.py} (100%)
rename examples/{07n-interruptible-gemini.py => services/speech/google-gemini-tts.py} (100%)
rename examples/{07n-interruptible-google-http.py => services/speech/google-http.py} (100%)
rename examples/{07n-interruptible-gemini-image.py => services/speech/google-image.py} (100%)
rename examples/{07n-interruptible-google.py => services/speech/google.py} (100%)
rename examples/{07zf-interruptible-gradium.py => services/speech/gradium.py} (100%)
rename examples/{07l-interruptible-groq.py => services/speech/groq.py} (100%)
rename examples/{07ze-interruptible-hume.py => services/speech/hume.py} (100%)
rename examples/{07zb-interruptible-inworld-http.py => services/speech/inworld-http.py} (100%)
rename examples/{07zb-interruptible-inworld.py => services/speech/inworld.py} (100%)
rename examples/{07zj-interruptible-kokoro.py => services/speech/kokoro.py} (100%)
rename examples/{07p-interruptible-krisp-viva.py => services/speech/krisp-viva.py} (100%)
rename examples/{07b-interruptible-langchain.py => services/speech/langchain.py} (100%)
rename examples/{07k-interruptible-lmnt.py => services/speech/lmnt.py} (100%)
rename examples/{07y-interruptible-minimax.py => services/speech/minimax.py} (100%)
rename examples/{07v-interruptible-neuphonic-http.py => services/speech/neuphonic-http.py} (100%)
rename examples/{07v-interruptible-neuphonic.py => services/speech/neuphonic.py} (100%)
rename examples/{07r-interruptible-nvidia.py => services/speech/nvidia.py} (100%)
rename examples/{07g-interruptible-openai-http.py => services/speech/openai-http.py} (100%)
rename examples/{07-interruptible-openai-responses-http.py => services/speech/openai-responses-http.py} (100%)
rename examples/{07-interruptible-openai-responses.py => services/speech/openai-responses.py} (100%)
rename examples/{07g-interruptible-openai.py => services/speech/openai.py} (100%)
rename examples/{07zi-interruptible-piper.py => services/speech/piper.py} (100%)
rename examples/{07zk-interruptible-resemble.py => services/speech/resemble.py} (100%)
rename examples/{07q-interruptible-rime-http.py => services/speech/rime-http.py} (100%)
rename examples/{07q-interruptible-rime.py => services/speech/rime.py} (100%)
rename examples/{07z-interruptible-sarvam-http.py => services/speech/sarvam-http.py} (100%)
rename examples/{07z-interruptible-sarvam.py => services/speech/sarvam.py} (100%)
rename examples/{07zl-interruptible-smallest.py => services/speech/smallest.py} (100%)
rename examples/{07za-interruptible-soniox.py => services/speech/soniox.py} (100%)
rename examples/{07a-interruptible-speechmatics-vad.py => services/speech/speechmatics-vad.py} (100%)
rename examples/{07a-interruptible-speechmatics.py => services/speech/speechmatics.py} (100%)
rename examples/{07e-interruptible-xai.py => services/speech/xai.py} (100%)
rename examples/{07i-interruptible-xtts.py => services/speech/xtts.py} (100%)
rename examples/{39-mcp-stdio.py => thinking-and-mcp/mcp-stdio.py} (100%)
rename examples/{39b-mcp-streamable-http-gemini-live.py => thinking-and-mcp/mcp-streamable-http-gemini-live.py} (100%)
rename examples/{39a-mcp-streamable-http.py => thinking-and-mcp/mcp-streamable-http.py} (100%)
rename examples/{39c-multiple-mcp.py => thinking-and-mcp/multiple-mcp.py} (100%)
rename examples/{49a-thinking-anthropic.py => thinking-and-mcp/thinking-anthropic.py} (100%)
rename examples/{49c-thinking-functions-anthropic.py => thinking-and-mcp/thinking-functions-anthropic.py} (100%)
rename examples/{49d-thinking-functions-google.py => thinking-and-mcp/thinking-functions-google.py} (100%)
rename examples/{49b-thinking-google.py => thinking-and-mcp/thinking-google.py} (100%)
rename examples/{13d-assemblyai-transcription.py => transcription/assemblyai.py} (100%)
rename examples/{13j-azure-transcription.py => transcription/azure.py} (100%)
rename examples/{13f-cartesia-transcription.py => transcription/cartesia.py} (100%)
rename examples/{13b-deepgram-transcription.py => transcription/deepgram.py} (100%)
rename examples/{13k-elevenlabs-transcription.py => transcription/elevenlabs.py} (100%)
rename examples/{13c-gladia-transcription.py => transcription/gladia-transcription.py} (100%)
rename examples/{13c-gladia-translation.py => transcription/gladia-translation.py} (100%)
rename examples/{25-google-audio-in.py => transcription/google-llm.py} (100%)
rename examples/{13l-gradium-transcription.py => transcription/gradium.py} (100%)
rename examples/{13m-openai-transcription.py => transcription/openai.py} (100%)
rename examples/{13i-soniox-transcription.py => transcription/soniox.py} (100%)
rename examples/{13h-speechmatics-transcription.py => transcription/speechmatics.py} (100%)
rename examples/{13a-whisper-local.py => transcription/whisper-local.py} (100%)
rename examples/{13e-whisper-mlx.py => transcription/whisper-mlx.py} (100%)
rename examples/{13-whisper-transcription.py => transcription/whisper.py} (100%)
rename examples/{04a-transports-daily.py => transports/daily.py} (100%)
rename examples/{04b-transports-livekit.py => transports/livekit.py} (100%)
rename examples/{04-transports-small-webrtc.py => transports/small-webrtc.py} (100%)
rename examples/{17-detect-user-idle.py => turn-management/detect-user-idle.py} (100%)
rename examples/{22-filter-incomplete-turns.py => turn-management/filter-incomplete-turns.py} (100%)
rename examples/{42-interruption-config.py => turn-management/interruption-config.py} (100%)
rename examples/{38a-smart-turn-local-coreml.py => turn-management/smart-turn-local-coreml.py} (100%)
rename examples/{38b-smart-turn-local.py => turn-management/smart-turn-local.py} (100%)
rename examples/{29-turn-tracking-observer.py => turn-management/turn-tracking-observer.py} (100%)
rename examples/{28-user-assistant-turns.py => turn-management/user-assistant-turns.py} (100%)
rename examples/{24-user-mute-strategy.py => turn-management/user-mute-strategy.py} (100%)
rename examples/{55zj-update-settings-anthropic-llm.py => update-settings/llm/anthropic.py} (100%)
rename examples/{55zp-update-settings-aws-bedrock-llm.py => update-settings/llm/aws-bedrock.py} (100%)
rename examples/{55zzk-update-settings-aws-nova-sonic-llm.py => update-settings/llm/aws-nova-sonic.py} (100%)
rename examples/{55zl-update-settings-azure-realtime.py => update-settings/llm/azure-realtime.py} (100%)
rename examples/{55zi-update-settings-azure-llm.py => update-settings/llm/azure.py} (100%)
rename examples/{55zx-update-settings-cerebras-llm.py => update-settings/llm/cerebras.py} (100%)
rename examples/{55zy-update-settings-deepseek-llm.py => update-settings/llm/deepseek.py} (100%)
rename examples/{55zz-update-settings-fireworks-llm.py => update-settings/llm/fireworks.py} (100%)
rename examples/{55zm-update-settings-gemini-live-vertex.py => update-settings/llm/gemini-live-vertex.py} (100%)
rename examples/{55zm-update-settings-gemini-live.py => update-settings/llm/gemini-live.py} (100%)
rename examples/{55zk-update-settings-google-vertex-llm.py => update-settings/llm/google-vertex.py} (100%)
rename examples/{55zk-update-settings-google-llm.py => update-settings/llm/google.py} (100%)
rename examples/{55zo-update-settings-grok-realtime.py => update-settings/llm/grok-realtime.py} (100%)
rename examples/{55zza-update-settings-grok-llm.py => update-settings/llm/grok.py} (100%)
rename examples/{55zzb-update-settings-groq-llm.py => update-settings/llm/groq.py} (100%)
rename examples/{55zzc-update-settings-mistral-llm.py => update-settings/llm/mistral.py} (100%)
rename examples/{55zzd-update-settings-nvidia-llm.py => update-settings/llm/nvidia.py} (100%)
rename examples/{55zze-update-settings-ollama-llm.py => update-settings/llm/ollama.py} (100%)
rename examples/{55zl-update-settings-openai-realtime.py => update-settings/llm/openai-realtime.py} (100%)
rename examples/{55zi-update-settings-openai-responses-http-llm.py => update-settings/llm/openai-responses-http.py} (100%)
rename examples/{55zi-update-settings-openai-responses-llm.py => update-settings/llm/openai-responses.py} (100%)
rename examples/{55zi-update-settings-openai-llm.py => update-settings/llm/openai.py} (100%)
rename examples/{55zzf-update-settings-openrouter-llm.py => update-settings/llm/openrouter.py} (100%)
rename examples/{55zzg-update-settings-perplexity-llm.py => update-settings/llm/perplexity.py} (100%)
rename examples/{55zzh-update-settings-qwen-llm.py => update-settings/llm/qwen.py} (100%)
rename examples/{55zzi-update-settings-sambanova-llm.py => update-settings/llm/sambanova.py} (100%)
rename examples/{55zzq-update-settings-sarvam-llm.py => update-settings/llm/sarvam.py} (100%)
rename examples/{55zzj-update-settings-together-llm.py => update-settings/llm/together.py} (100%)
rename examples/{55zn-update-settings-ultravox-realtime.py => update-settings/llm/ultravox-realtime.py} (100%)
rename examples/{55d-update-settings-assemblyai-stt.py => update-settings/stt/assemblyai.py} (100%)
rename examples/{55l-update-settings-aws-transcribe-stt.py => update-settings/stt/aws-transcribe.py} (100%)
rename examples/{55b-update-settings-azure-stt.py => update-settings/stt/azure.py} (100%)
rename examples/{55m-update-settings-cartesia-stt.py => update-settings/stt/cartesia.py} (100%)
rename examples/{55a-update-settings-deepgram-flux-stt.py => update-settings/stt/deepgram-flux.py} (100%)
rename examples/{55a-update-settings-deepgram-sagemaker-stt.py => update-settings/stt/deepgram-sagemaker.py} (100%)
rename examples/{55a-update-settings-deepgram-stt.py => update-settings/stt/deepgram.py} (100%)
rename examples/{55f-update-settings-elevenlabs-realtime-stt.py => update-settings/stt/elevenlabs-realtime.py} (100%)
rename examples/{55g-update-settings-elevenlabs-stt.py => update-settings/stt/elevenlabs.py} (100%)
rename examples/{55zq-update-settings-fal-stt.py => update-settings/stt/fal.py} (100%)
rename examples/{55e-update-settings-gladia-stt.py => update-settings/stt/gladia.py} (100%)
rename examples/{55c-update-settings-google-stt.py => update-settings/stt/google.py} (100%)
rename examples/{55zr-update-settings-gradium-stt.py => update-settings/stt/gradium.py} (100%)
rename examples/{55zzn-update-settings-groq-stt.py => update-settings/stt/groq.py} (100%)
rename examples/{55zt-update-settings-nvidia-segmented-stt.py => update-settings/stt/nvidia-segmented.py} (100%)
rename examples/{55zt-update-settings-nvidia-stt.py => update-settings/stt/nvidia.py} (100%)
rename examples/{55zu-update-settings-openai-realtime-stt.py => update-settings/stt/openai-realtime.py} (100%)
rename examples/{55j-update-settings-sarvam-stt.py => update-settings/stt/sarvam.py} (100%)
rename examples/{55k-update-settings-soniox-stt.py => update-settings/stt/soniox.py} (100%)
rename examples/{55h-update-settings-speechmatics-stt.py => update-settings/stt/speechmatics.py} (100%)
rename examples/{55i-update-settings-whisper-api-stt.py => update-settings/stt/whisper-api.py} (100%)
rename examples/{55zs-update-settings-whisper-mlx-stt.py => update-settings/stt/whisper-mlx.py} (100%)
rename examples/{55zs-update-settings-whisper-stt.py => update-settings/stt/whisper.py} (100%)
rename examples/{55zv-update-settings-asyncai-http-tts.py => update-settings/tts/asyncai-http.py} (100%)
rename examples/{55zv-update-settings-asyncai-tts.py => update-settings/tts/asyncai.py} (100%)
rename examples/{55zd-update-settings-aws-polly-tts.py => update-settings/tts/aws-polly.py} (100%)
rename examples/{55r-update-settings-azure-http-tts.py => update-settings/tts/azure-http.py} (100%)
rename examples/{55r-update-settings-azure-tts.py => update-settings/tts/azure.py} (100%)
rename examples/{55zf-update-settings-camb-tts.py => update-settings/tts/camb.py} (100%)
rename examples/{55n-update-settings-cartesia-http-tts.py => update-settings/tts/cartesia-http.py} (100%)
rename examples/{55n-update-settings-cartesia-tts.py => update-settings/tts/cartesia.py} (100%)
rename examples/{55q-update-settings-deepgram-http-tts.py => update-settings/tts/deepgram-http.py} (100%)
rename examples/{55q-update-settings-deepgram-sagemaker-tts.py => update-settings/tts/deepgram-sagemaker.py} (100%)
rename examples/{55q-update-settings-deepgram-tts.py => update-settings/tts/deepgram.py} (100%)
rename examples/{55o-update-settings-elevenlabs-http-tts.py => update-settings/tts/elevenlabs-http.py} (100%)
rename examples/{55o-update-settings-elevenlabs-tts.py => update-settings/tts/elevenlabs.py} (100%)
rename examples/{55w-update-settings-fish-tts.py => update-settings/tts/fish.py} (100%)
rename examples/{55zc-update-settings-gemini-tts.py => update-settings/tts/gemini.py} (100%)
rename examples/{55s-update-settings-google-http-tts.py => update-settings/tts/google-http.py} (100%)
rename examples/{55s-update-settings-google-stream-tts.py => update-settings/tts/google-stream.py} (100%)
rename examples/{55zw-update-settings-gradium-tts.py => update-settings/tts/gradium.py} (100%)
rename examples/{55y-update-settings-groq-tts.py => update-settings/tts/groq.py} (100%)
rename examples/{55z-update-settings-hume-tts.py => update-settings/tts/hume.py} (100%)
rename examples/{55zb-update-settings-inworld-http-tts.py => update-settings/tts/inworld-http.py} (100%)
rename examples/{55zb-update-settings-inworld-tts.py => update-settings/tts/inworld.py} (100%)
rename examples/{55zg-update-settings-kokoro-tts.py => update-settings/tts/kokoro.py} (100%)
rename examples/{55v-update-settings-lmnt-tts.py => update-settings/tts/lmnt.py} (100%)
rename examples/{55x-update-settings-minimax-tts.py => update-settings/tts/minimax.py} (100%)
rename examples/{55za-update-settings-neuphonic-http-tts.py => update-settings/tts/neuphonic-http.py} (100%)
rename examples/{55za-update-settings-neuphonic-tts.py => update-settings/tts/neuphonic.py} (100%)
rename examples/{55zzl-update-settings-nvidia-tts.py => update-settings/tts/nvidia.py} (100%)
rename examples/{55p-update-settings-openai-tts.py => update-settings/tts/openai.py} (100%)
rename examples/{55t-update-settings-piper-http-tts.py => update-settings/tts/piper-http.py} (100%)
rename examples/{55t-update-settings-piper-tts.py => update-settings/tts/piper.py} (100%)
rename examples/{55zh-update-settings-resembleai-tts.py => update-settings/tts/resembleai.py} (100%)
rename examples/{55u-update-settings-rime-http-tts.py => update-settings/tts/rime-http.py} (100%)
rename examples/{55u-update-settings-rime-tts.py => update-settings/tts/rime.py} (100%)
rename examples/{55ze-update-settings-sarvam-http-tts.py => update-settings/tts/sarvam-http.py} (100%)
rename examples/{55ze-update-settings-sarvam-tts.py => update-settings/tts/sarvam.py} (100%)
rename examples/{55zzm-update-settings-speechmatics-tts.py => update-settings/tts/speechmatics.py} (100%)
rename examples/{55zzp-update-settings-xtts-tts.py => update-settings/tts/xtts.py} (100%)
rename examples/{43-heygen-transport.py => video-avatar/heygen-transport.py} (100%)
rename examples/{43a-heygen-video-service.py => video-avatar/heygen-video-service.py} (100%)
rename examples/{56-lemonslice-transport.py => video-avatar/lemonslice-transport.py} (100%)
rename examples/{27-simli-layer.py => video-avatar/simli-layer.py} (100%)
rename examples/{21-tavus-transport.py => video-avatar/tavus-transport.py} (100%)
rename examples/{21a-tavus-video-service.py => video-avatar/tavus-video-service.py} (100%)
rename examples/{57-custom-video-track.py => video-processing/custom-video-track.py} (100%)
rename examples/{18-gstreamer-filesrc.py => video-processing/gstreamer-filesrc.py} (100%)
rename examples/{18a-gstreamer-videotestsrc.py => video-processing/gstreamer-videotestsrc.py} (100%)
rename examples/{09a-local-mirror.py => video-processing/local-mirror.py} (100%)
rename examples/{09-mirror.py => video-processing/mirror.py} (100%)
rename examples/{46-video-processing.py => video-processing/video-processing.py} (100%)
rename examples/{12a-describe-image-anthropic.py => vision/anthropic.py} (100%)
rename examples/{12b-describe-image-aws.py => vision/aws.py} (100%)
rename examples/{12c-describe-image-gemini-flash.py => vision/gemini-flash.py} (100%)
rename examples/{12d-describe-image-moondream.py => vision/moondream.py} (100%)
rename examples/{12-describe-image-openai-responses-http.py => vision/openai-responses-http.py} (100%)
rename examples/{12-describe-image-openai-responses.py => vision/openai-responses.py} (100%)
rename examples/{12-describe-image-openai.py => vision/openai.py} (100%)
diff --git a/README.md b/README.md
index 78b359d07..af165a94f 100644
--- a/README.md
+++ b/README.md
@@ -80,7 +80,7 @@ Catch new features, interviews, and how-tos on our [Pipecat TV](https://www.yout
-
+
## 🧩 Available services
diff --git a/examples/01-say-one-thing-piper.py b/examples/01-say-one-thing-piper.py
deleted file mode 100644
index 6c4e1836e..000000000
--- a/examples/01-say-one-thing-piper.py
+++ /dev/null
@@ -1,71 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
-
-import os
-
-import aiohttp
-from dotenv import load_dotenv
-from loguru import logger
-
-from pipecat.frames.frames import EndFrame, TTSSpeakFrame
-from pipecat.pipeline.pipeline import Pipeline
-from pipecat.pipeline.runner import PipelineRunner
-from pipecat.pipeline.task import PipelineTask
-from pipecat.runner.types import RunnerArguments
-from pipecat.runner.utils import create_transport
-from pipecat.services.piper.tts import PiperHttpTTSService
-from pipecat.transports.base_transport import BaseTransport, TransportParams
-from pipecat.transports.daily.transport import DailyParams
-from pipecat.transports.websocket.fastapi import FastAPIWebsocketParams
-
-load_dotenv(override=True)
-
-
-# We use lambdas to defer transport parameter creation until the transport
-# type is selected at runtime.
-transport_params = {
- "daily": lambda: DailyParams(audio_out_enabled=True),
- "twilio": lambda: FastAPIWebsocketParams(audio_out_enabled=True),
- "webrtc": lambda: TransportParams(audio_out_enabled=True),
-}
-
-
-async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
- logger.info(f"Starting bot")
-
- # Create an HTTP session
- async with aiohttp.ClientSession() as session:
- tts = PiperHttpTTSService(
- base_url=os.getenv("PIPER_BASE_URL"),
- aiohttp_session=session,
- sample_rate=24000,
- )
-
- task = PipelineTask(
- Pipeline([tts, transport.output()]),
- idle_timeout_secs=runner_args.pipeline_idle_timeout_secs,
- )
-
- # Register an event handler so we can play the audio when the client joins
- @transport.event_handler("on_client_connected")
- async def on_client_connected(transport, client):
- await task.queue_frames([TTSSpeakFrame(f"Hello there!"), EndFrame()])
-
- runner = PipelineRunner(handle_sigint=runner_args.handle_sigint)
-
- await runner.run(task)
-
-
-async def bot(runner_args: RunnerArguments):
- """Main bot entry point compatible with Pipecat Cloud."""
- transport = await create_transport(runner_args, transport_params)
- await run_bot(transport, runner_args)
-
-
-if __name__ == "__main__":
- from pipecat.runner.run import main
-
- main()
diff --git a/examples/01-say-one-thing-rime.py b/examples/01-say-one-thing-rime.py
deleted file mode 100644
index a9df51f7f..000000000
--- a/examples/01-say-one-thing-rime.py
+++ /dev/null
@@ -1,72 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
-
-import os
-
-import aiohttp
-from dotenv import load_dotenv
-from loguru import logger
-
-from pipecat.frames.frames import EndFrame, TTSSpeakFrame
-from pipecat.pipeline.pipeline import Pipeline
-from pipecat.pipeline.runner import PipelineRunner
-from pipecat.pipeline.task import PipelineTask
-from pipecat.runner.types import RunnerArguments
-from pipecat.runner.utils import create_transport
-from pipecat.services.rime.tts import RimeHttpTTSService
-from pipecat.transports.base_transport import BaseTransport, TransportParams
-from pipecat.transports.daily.transport import DailyParams
-from pipecat.transports.websocket.fastapi import FastAPIWebsocketParams
-
-load_dotenv(override=True)
-
-# We use lambdas to defer transport parameter creation until the transport
-# type is selected at runtime.
-transport_params = {
- "daily": lambda: DailyParams(audio_out_enabled=True),
- "twilio": lambda: FastAPIWebsocketParams(audio_out_enabled=True),
- "webrtc": lambda: TransportParams(audio_out_enabled=True),
-}
-
-
-async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
- logger.info(f"Starting bot")
-
- # Create an HTTP session
- async with aiohttp.ClientSession() as session:
- tts = RimeHttpTTSService(
- api_key=os.getenv("RIME_API_KEY", ""),
- aiohttp_session=session,
- settings=RimeHttpTTSService.Settings(
- voice="rex",
- ),
- )
-
- task = PipelineTask(
- Pipeline([tts, transport.output()]),
- idle_timeout_secs=runner_args.pipeline_idle_timeout_secs,
- )
-
- # Register an event handler so we can play the audio when the client joins
- @transport.event_handler("on_client_connected")
- async def on_client_connected(transport, client):
- await task.queue_frames([TTSSpeakFrame(f"Hello there!"), EndFrame()])
-
- runner = PipelineRunner(handle_sigint=runner_args.handle_sigint)
-
- await runner.run(task)
-
-
-async def bot(runner_args: RunnerArguments):
- """Main bot entry point compatible with Pipecat Cloud."""
- transport = await create_transport(runner_args, transport_params)
- await run_bot(transport, runner_args)
-
-
-if __name__ == "__main__":
- from pipecat.runner.run import main
-
- main()
diff --git a/examples/01b-livekit-audio.py b/examples/01b-livekit-audio.py
deleted file mode 100644
index 5f64a29ed..000000000
--- a/examples/01b-livekit-audio.py
+++ /dev/null
@@ -1,64 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
-
-import asyncio
-import os
-import sys
-
-from dotenv import load_dotenv
-from loguru import logger
-
-from pipecat.frames.frames import TTSSpeakFrame
-from pipecat.pipeline.pipeline import Pipeline
-from pipecat.pipeline.runner import PipelineRunner
-from pipecat.pipeline.task import PipelineTask
-from pipecat.runner.livekit import configure
-from pipecat.services.cartesia.tts import CartesiaTTSService
-from pipecat.transports.livekit.transport import LiveKitParams, LiveKitTransport
-
-load_dotenv(override=True)
-
-logger.remove(0)
-logger.add(sys.stderr, level="DEBUG")
-
-
-async def main():
- (url, token, room_name) = await configure()
-
- transport = LiveKitTransport(
- url=url,
- token=token,
- room_name=room_name,
- params=LiveKitParams(audio_out_enabled=True),
- )
-
- tts = CartesiaTTSService(
- api_key=os.getenv("CARTESIA_API_KEY"),
- settings=CartesiaTTSService.Settings(
- voice="71a7ad14-091c-4e8e-a314-022ece01c121", # British Reading Lady
- ),
- )
-
- runner = PipelineRunner()
-
- task = PipelineTask(Pipeline([tts, transport.output()]))
-
- # Register an event handler so we can play the audio when the
- # participant joins.
- @transport.event_handler("on_first_participant_joined")
- async def on_first_participant_joined(transport, participant_id):
- await asyncio.sleep(1)
- await task.queue_frame(
- TTSSpeakFrame(
- "Hello there! How are you doing today? Would you like to talk about the weather?"
- )
- )
-
- await runner.run(task)
-
-
-if __name__ == "__main__":
- asyncio.run(main())
diff --git a/examples/01c-nvidia-riva-tts.py b/examples/01c-nvidia-riva-tts.py
deleted file mode 100644
index 2be99c5b4..000000000
--- a/examples/01c-nvidia-riva-tts.py
+++ /dev/null
@@ -1,64 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
-
-import os
-
-from dotenv import load_dotenv
-from loguru import logger
-
-from pipecat.frames.frames import EndFrame, TTSSpeakFrame
-from pipecat.pipeline.pipeline import Pipeline
-from pipecat.pipeline.runner import PipelineRunner
-from pipecat.pipeline.task import PipelineTask
-from pipecat.runner.types import RunnerArguments
-from pipecat.runner.utils import create_transport
-from pipecat.services.nvidia.tts import NvidiaTTSService
-from pipecat.transports.base_transport import BaseTransport, TransportParams
-from pipecat.transports.daily.transport import DailyParams
-from pipecat.transports.websocket.fastapi import FastAPIWebsocketParams
-
-load_dotenv(override=True)
-
-
-# We use lambdas to defer transport parameter creation until the transport
-# type is selected at runtime.
-transport_params = {
- "daily": lambda: DailyParams(audio_out_enabled=True),
- "twilio": lambda: FastAPIWebsocketParams(audio_out_enabled=True),
- "webrtc": lambda: TransportParams(audio_out_enabled=True),
-}
-
-
-async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
- logger.info(f"Starting bot")
-
- tts = NvidiaTTSService(api_key=os.getenv("NVIDIA_API_KEY"))
-
- task = PipelineTask(
- Pipeline([tts, transport.output()]),
- idle_timeout_secs=runner_args.pipeline_idle_timeout_secs,
- )
-
- # Register an event handler so we can play the audio when the client joins
- @transport.event_handler("on_client_connected")
- async def on_client_connected(transport, client):
- await task.queue_frames([TTSSpeakFrame(f"Hello there!"), EndFrame()])
-
- runner = PipelineRunner(handle_sigint=runner_args.handle_sigint)
-
- await runner.run(task)
-
-
-async def bot(runner_args: RunnerArguments):
- """Main bot entry point compatible with Pipecat Cloud."""
- transport = await create_transport(runner_args, transport_params)
- await run_bot(transport, runner_args)
-
-
-if __name__ == "__main__":
- from pipecat.runner.run import main
-
- main()
diff --git a/examples/03-still-frame.py b/examples/03-still-frame.py
deleted file mode 100644
index dc1bf4c5f..000000000
--- a/examples/03-still-frame.py
+++ /dev/null
@@ -1,84 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
-
-import os
-
-import aiohttp
-from dotenv import load_dotenv
-from loguru import logger
-
-from pipecat.frames.frames import TextFrame
-from pipecat.pipeline.pipeline import Pipeline
-from pipecat.pipeline.runner import PipelineRunner
-from pipecat.pipeline.task import PipelineTask
-from pipecat.runner.types import RunnerArguments
-from pipecat.runner.utils import create_transport
-from pipecat.services.fal.image import FalImageGenService
-from pipecat.transports.base_transport import BaseTransport, TransportParams
-from pipecat.transports.daily.transport import DailyParams
-
-load_dotenv(override=True)
-
-
-# We use lambdas to defer transport parameter creation until the transport
-# type is selected at runtime.
-transport_params = {
- "daily": lambda: DailyParams(
- video_out_enabled=True,
- video_out_width=1024,
- video_out_height=1024,
- ),
- "webrtc": lambda: TransportParams(
- video_out_enabled=True,
- video_out_width=1024,
- video_out_height=1024,
- ),
-}
-
-
-async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
- logger.info(f"Starting bot")
-
- # Create an HTTP session
- async with aiohttp.ClientSession() as session:
- imagegen = FalImageGenService(
- settings=FalImageGenService.Settings(
- image_size="square_hd",
- ),
- aiohttp_session=session,
- key=os.getenv("FAL_KEY"),
- )
-
- task = PipelineTask(
- Pipeline([imagegen, transport.output()]),
- idle_timeout_secs=runner_args.pipeline_idle_timeout_secs,
- )
-
- # Register an event handler so we can play the audio when the client joins
- @transport.event_handler("on_client_connected")
- async def on_client_connected(transport, client):
- await task.queue_frame(TextFrame("a cat in the style of picasso"))
-
- @transport.event_handler("on_client_disconnected")
- async def on_client_disconnected(transport, client):
- logger.info(f"Client disconnected")
- await task.cancel()
-
- runner = PipelineRunner(handle_sigint=runner_args.handle_sigint)
-
- await runner.run(task)
-
-
-async def bot(runner_args: RunnerArguments):
- """Main bot entry point compatible with Pipecat Cloud."""
- transport = await create_transport(runner_args, transport_params)
- await run_bot(transport, runner_args)
-
-
-if __name__ == "__main__":
- from pipecat.runner.run import main
-
- main()
diff --git a/examples/README.md b/examples/README.md
index e8a0dd9bf..f584d3768 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -1,6 +1,6 @@
# Pipecat Examples
-This directory contains examples showing how to build voice and multimodal agents with Pipecat. Each example demonstrates specific features, progressing from basic to advanced concepts.
+This directory contains examples showing how to build voice and multimodal agents with Pipecat.
## Setup
@@ -17,19 +17,13 @@ This directory contains examples showing how to build voice and multimodal agent
# Edit .env with your API keys
```
-3. Navigate to the examples directory if you aren't already there:
+3. Run any example:
```bash
- cd examples
+ uv run python getting-started/01-say-one-thing.py
```
-4. Run any example:
-
- ```bash
- uv run python 01-say-one-thing.py
- ```
-
-5. Open the web interface at http://localhost:7860/client/ and click "Connect"
+4. Open the web interface at http://localhost:7860/client/ and click "Connect"
## Running examples with other transports
@@ -40,7 +34,7 @@ Most examples support running with other transports, like Twilio or Daily.
You need to create a Daily account at https://dashboard.daily.co/u/signup. Once signed up, you can create your own room from the dashboard and set the environment variables `DAILY_ROOM_URL` and `DAILY_API_KEY`. Alternatively, you can let the example create a room for you (still needs `DAILY_API_KEY` environment variable). Then, start any example with `-t daily`:
```bash
-uv run 07-interruptible.py -t daily
+uv run getting-started/06-voice-agent.py -t daily
```
### Twilio
@@ -58,74 +52,73 @@ ngrok http 7860
Then, run the example with:
```bash
-uv run 07-interruptible.py -t twilio -x NGROK_HOST_NAME
+uv run getting-started/06-voice-agent.py -t twilio -x NGROK_HOST_NAME
```
-## Examples by Feature
+## Directory Structure
-### Basics
+### [`getting-started/`](./getting-started/)
-- **[01-say-one-thing.py](./01-say-one-thing.py)**: Most basic bot that says one phrase and exits (Transport, TTS, Event handlers)
-- **[02-llm-say-one-thing.py](./02-llm-say-one-thing.py)**: Bot generates a response with an LLM (LLM initialization)
-- **[03-still-frame.py](./03-still-frame.py)**: Displays a static image (Video transport, Image service)
-- **[04-transport.py](./04-transport.py)**: Different transport options (WebRTC, Daily, Livekit)
+Progressive introduction to Pipecat, from minimal TTS to a full voice agent with function calling.
-### Conversational AI
+### [`services/`](./services/)
-- **[07-interruptible.py](./07-interruptible.py)**: Basic voice assistant bot (STT, TTS, LLM, Interruptible speech)
-- **[10-wake-phrase.py](./10-wake-phrase.py)**: Bot activated by wake phrase (WakeCheckFilter)
-- **[22-natural-conversation.py](./22-natural-conversation.py)**: Smart turn detection (Multiple LLMs, Turn management)
-- **[38-smart-turn-fal.py](./38-smart-turn-fal.py)**: ML-based turn detection (Fal service, Local models)
+Service provider integration examples, organized into subfolders:
-### Common Utilities
+- **[`speech/`](./services/speech/)** — Full STT + LLM + TTS pipelines showcasing different speech service providers (Deepgram, ElevenLabs, Cartesia, etc.)
+- **[`function-calling/`](./services/function-calling/)** — Function calling with different LLM providers (OpenAI, Anthropic, Google, etc.)
-- **[17-detect-user-idle.py](./17-detect-user-idle.py)**: Handle inactive users (UserIdleProcessor)
-- **[24-user-mute-strategy.py](./24-user-mute-strategy.py)**: Selectively mute user input (LLMUserAggregator user mute strategies)
-- **[28-transcription-processor.py](./28-transcription-processor.py)**: Record conversation text (TranscriptProcessor)
-- **[30-observer.py](./30-observer.py)**: Access frame data (Custom observers)
-- **[31-heartbeats.py](./31-heartbeats.py)**: Detect idle pipelines (Pipeline monitoring)
-- **[34-audio-recording.py](./34-audio-recording.py)**: Record conversation audio (Composite and track-level recording)
+### [`transcription/`](./transcription/)
-### Advanced LLM Features
+Speech-to-text examples with various STT providers.
-- **[14-function-calling.py](./14-function-calling.py)**: Bot with tool usage (Function schemas, Tool registration)
-- **[20a-persistent-context-openai.py](./20a-persistent-context-openai.py)**: Persistent conversation context (Memory management)
-- **[32-gemini-grounding-metadata.py](./32-gemini-grounding-metadata.py)**: Web search capabilities (Google search integration)
-- **[33-gemini-rag.py](./33-gemini-rag.py)**: Retrieval-augmented generation (Data sources, Grounding)
-- **[37-mem0.py](./37-mem0.py)**: Long-term agent memory (Mem0 service integration)
+### [`vision/`](./vision/)
-### Media Handling
+Image description and vision capabilities with different multimodal LLMs.
-- **[05-sync-speech-and-images.py](./05-sync-speech-and-images.py)**: Synchronized narration with images (Custom processors, SyncParallelPipeline)
-- **[06a-image-sync.py](./06a-image-sync.py)**: Dynamic image updates while speaking (Synchronized A/V pipelines)
-- **[09-mirror.py](./09-mirror.py)**: Mirror user's audio and video (Custom frame processors)
-- **[11-sound-effects.py](./11-sound-effects.py)**: Add sounds when bot speaks (Sound playback, Event synchronization)
-- **[23-bot-background-sound.py](./23-bot-background-sound.py)**: Play background audio (SoundfileMixer)
+### [`realtime/`](./realtime/)
-### Vision & Multimodal
+Realtime and multimodal live APIs (OpenAI Realtime, Gemini Live, AWS Nova Sonic, Ultravox, Grok).
-- **[12a-describe-video-gemini-flash.py](./12a-describe-video-gemini-flash.py)**: Bot describes user's video (Video input, Multimodal LLMs)
-- **[26c-gemini-live-video.py](./26c-gemini-live-video.py)**: Gemini with video input (Streaming video, Function calls)
+### [`persistent-context/`](./persistent-context/)
-### Voice & Language
+Maintaining conversation context across sessions with different providers.
-- **[13-transcription.py](./13-transcription.py)**: Speech transcription demo (STT providers, Real-time transcription)
-- **[15-switch-voices.py](./15-switch-voices.py)**: Dynamic voice/language changing (ParallelPipelines, FunctionFilters)
-- **[25-google-audio-in.py](./25-google-audio-in.py)**: Gemini for speech recognition (Alternative transcription)
-- **[35-pattern-pair-voice-switching.py](./35-pattern-pair-voice-switching.py)**: Dynamic TTS voice switching (XML parsing, PatternPairAggregator)
-- **[36-user-email-gathering.py](./36-user-email-gathering.py)**: Spelling mode for TTS (Confirmation patterns, XML tags)
+### [`context-summarization/`](./context-summarization/)
-### Integration Examples
+Summarizing conversation context to manage token limits.
-- **[18-gstreamer-filesrc.py](./18-gstreamer-filesrc.py)**: GStreamer video streaming (Video processing)
-- **[19-openai-realtime-beta.py](./19-openai-realtime-beta.py)**: OpenAI Speech-to-Speech (Direct S2S, Function calls)
-- **[21-tavus-layer-tavus-transport.py](./21-tavus-layer-tavus-transport.py)**: Tavus digital twin (Avatar integration)
-- **[27-simli-layer.py](./27-simli-layer.py)**: Simli avatar integration (Video synchronization)
-- **[56-lemonslice-transport.py](./56-lemonslice-transport.py)**: LemonSlice avatar integration (A/V Synced Avatar integration)
+### [`update-settings/`](./update-settings/)
-### Performance & Optimization
+Changing service settings at runtime, organized by service type:
-- **[16-gpu-container-local-bot.py](./16-gpu-container-local-bot.py)**: GPU-accelerated local bot (Performance measurement)
+- **[`stt/`](./update-settings/stt/)** — Speech-to-text settings
+- **[`tts/`](./update-settings/tts/)** — Text-to-speech settings
+- **[`llm/`](./update-settings/llm/)** — LLM settings
+
+### [`turn-management/`](./turn-management/)
+
+Turn detection, interruption handling, and user input management.
+
+### [`thinking-and-mcp/`](./thinking-and-mcp/)
+
+LLM thinking/reasoning modes and MCP (Model Context Protocol) tool server integration.
+
+### [`transports/`](./transports/)
+
+Transport layer examples (WebRTC, Daily, LiveKit).
+
+### [`video-avatar/`](./video-avatar/)
+
+Video avatar integrations (Tavus, HeyGen, Simli, LemonSlice).
+
+### [`video-processing/`](./video-processing/)
+
+Video processing, mirroring, GStreamer, and custom video tracks.
+
+### [`features/`](./features/)
+
+Miscellaneous features: sound effects, wake phrases, observers, audio recording, live translation, service switching, and more.
## Advanced Usage
@@ -141,4 +134,4 @@ uv run python --host 0.0.0.0 --port 8080
- **Connection errors**: Verify API keys in `.env` file
- **Port conflicts**: Use `--port` to change the port
-For more examples, visit our the [pipecat-examples repository](https://github.com/pipecat-ai/pipecat-examples).
+For more examples, visit the [pipecat-examples repository](https://github.com/pipecat-ai/pipecat-examples).
diff --git a/examples/54c-context-summarization-dedicated-llm.py b/examples/context-summarization/dedicated-llm.py
similarity index 100%
rename from examples/54c-context-summarization-dedicated-llm.py
rename to examples/context-summarization/dedicated-llm.py
diff --git a/examples/54a-context-summarization-google.py b/examples/context-summarization/google.py
similarity index 100%
rename from examples/54a-context-summarization-google.py
rename to examples/context-summarization/google.py
diff --git a/examples/54b-context-summarization-manual-openai.py b/examples/context-summarization/manual-openai.py
similarity index 100%
rename from examples/54b-context-summarization-manual-openai.py
rename to examples/context-summarization/manual-openai.py
diff --git a/examples/54-context-summarization-openai.py b/examples/context-summarization/openai.py
similarity index 100%
rename from examples/54-context-summarization-openai.py
rename to examples/context-summarization/openai.py
diff --git a/examples/34-audio-recording.py b/examples/features/audio-recording.py
similarity index 100%
rename from examples/34-audio-recording.py
rename to examples/features/audio-recording.py
diff --git a/examples/45-before-and-after-events.py b/examples/features/before-and-after-events.py
similarity index 100%
rename from examples/45-before-and-after-events.py
rename to examples/features/before-and-after-events.py
diff --git a/examples/23-bot-background-sound.py b/examples/features/bot-background-sound.py
similarity index 100%
rename from examples/23-bot-background-sound.py
rename to examples/features/bot-background-sound.py
diff --git a/examples/53-concurrent-llm-evaluation.py b/examples/features/concurrent-llm-evaluation.py
similarity index 100%
rename from examples/53-concurrent-llm-evaluation.py
rename to examples/features/concurrent-llm-evaluation.py
diff --git a/examples/53-concurrent-llm-rtvi-ignored-sources.py b/examples/features/concurrent-llm-rtvi-ignored-sources.py
similarity index 100%
rename from examples/53-concurrent-llm-rtvi-ignored-sources.py
rename to examples/features/concurrent-llm-rtvi-ignored-sources.py
diff --git a/examples/08-custom-frame-processor.py b/examples/features/custom-frame-processor.py
similarity index 100%
rename from examples/08-custom-frame-processor.py
rename to examples/features/custom-frame-processor.py
diff --git a/examples/32-gemini-grounding-metadata.py b/examples/features/gemini-grounding-metadata.py
similarity index 100%
rename from examples/32-gemini-grounding-metadata.py
rename to examples/features/gemini-grounding-metadata.py
diff --git a/examples/33-gemini-rag.py b/examples/features/gemini-rag.py
similarity index 100%
rename from examples/33-gemini-rag.py
rename to examples/features/gemini-rag.py
diff --git a/examples/16-gpu-container-local-bot.py b/examples/features/gpu-container-local-bot.py
similarity index 100%
rename from examples/16-gpu-container-local-bot.py
rename to examples/features/gpu-container-local-bot.py
diff --git a/examples/31-heartbeats.py b/examples/features/heartbeats.py
similarity index 100%
rename from examples/31-heartbeats.py
rename to examples/features/heartbeats.py
diff --git a/examples/52-live-translation.py b/examples/features/live-translation.py
similarity index 100%
rename from examples/52-live-translation.py
rename to examples/features/live-translation.py
diff --git a/examples/37-mem0.py b/examples/features/mem0.py
similarity index 100%
rename from examples/37-mem0.py
rename to examples/features/mem0.py
diff --git a/examples/30-observer.py b/examples/features/observer.py
similarity index 100%
rename from examples/30-observer.py
rename to examples/features/observer.py
diff --git a/examples/35-pattern-pair-voice-switching.py b/examples/features/pattern-pair-voice-switching.py
similarity index 100%
rename from examples/35-pattern-pair-voice-switching.py
rename to examples/features/pattern-pair-voice-switching.py
diff --git a/examples/47-sentry-metrics.py b/examples/features/sentry-metrics.py
similarity index 100%
rename from examples/47-sentry-metrics.py
rename to examples/features/sentry-metrics.py
diff --git a/examples/48-service-switcher.py b/examples/features/service-switcher.py
similarity index 100%
rename from examples/48-service-switcher.py
rename to examples/features/service-switcher.py
diff --git a/examples/11-sound-effects.py b/examples/features/sound-effects.py
similarity index 100%
rename from examples/11-sound-effects.py
rename to examples/features/sound-effects.py
diff --git a/examples/15a-switch-languages.py b/examples/features/switch-languages.py
similarity index 100%
rename from examples/15a-switch-languages.py
rename to examples/features/switch-languages.py
diff --git a/examples/15-switch-voices.py b/examples/features/switch-voices.py
similarity index 100%
rename from examples/15-switch-voices.py
rename to examples/features/switch-voices.py
diff --git a/examples/36-user-email-gathering.py b/examples/features/user-email-gathering.py
similarity index 100%
rename from examples/36-user-email-gathering.py
rename to examples/features/user-email-gathering.py
diff --git a/examples/44-voicemail-detection.py b/examples/features/voicemail-detection.py
similarity index 100%
rename from examples/44-voicemail-detection.py
rename to examples/features/voicemail-detection.py
diff --git a/examples/10-wake-phrase.py b/examples/features/wake-phrase.py
similarity index 100%
rename from examples/10-wake-phrase.py
rename to examples/features/wake-phrase.py
diff --git a/examples/01-say-one-thing.py b/examples/getting-started/01-say-one-thing.py
similarity index 100%
rename from examples/01-say-one-thing.py
rename to examples/getting-started/01-say-one-thing.py
diff --git a/examples/01a-local-audio.py b/examples/getting-started/01a-local-audio.py
similarity index 100%
rename from examples/01a-local-audio.py
rename to examples/getting-started/01a-local-audio.py
diff --git a/examples/02-llm-say-one-thing.py b/examples/getting-started/02-llm-say-one-thing.py
similarity index 100%
rename from examples/02-llm-say-one-thing.py
rename to examples/getting-started/02-llm-say-one-thing.py
diff --git a/examples/03b-still-frame-imagen.py b/examples/getting-started/03-still-frame.py
similarity index 100%
rename from examples/03b-still-frame-imagen.py
rename to examples/getting-started/03-still-frame.py
diff --git a/examples/03a-local-still-frame.py b/examples/getting-started/03a-local-still-frame.py
similarity index 100%
rename from examples/03a-local-still-frame.py
rename to examples/getting-started/03a-local-still-frame.py
diff --git a/examples/05-sync-speech-and-image.py b/examples/getting-started/04-sync-speech-and-image.py
similarity index 100%
rename from examples/05-sync-speech-and-image.py
rename to examples/getting-started/04-sync-speech-and-image.py
diff --git a/examples/06a-image-sync.py b/examples/getting-started/05-speaking-state.py
similarity index 97%
rename from examples/06a-image-sync.py
rename to examples/getting-started/05-speaking-state.py
index 473441fac..36762f6b0 100644
--- a/examples/06a-image-sync.py
+++ b/examples/getting-started/05-speaking-state.py
@@ -119,8 +119,8 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
)
image_sync_aggregator = ImageSyncAggregator(
- os.path.join(os.path.dirname(__file__), "assets", "speaking.png"),
- os.path.join(os.path.dirname(__file__), "assets", "waiting.png"),
+ os.path.join(os.path.dirname(__file__), "..", "assets", "speaking.png"),
+ os.path.join(os.path.dirname(__file__), "..", "assets", "waiting.png"),
)
pipeline = Pipeline(
diff --git a/examples/07-interruptible.py b/examples/getting-started/06-voice-agent.py
similarity index 100%
rename from examples/07-interruptible.py
rename to examples/getting-started/06-voice-agent.py
diff --git a/examples/07x-interruptible-local.py b/examples/getting-started/06a-voice-agent-local.py
similarity index 100%
rename from examples/07x-interruptible-local.py
rename to examples/getting-started/06a-voice-agent-local.py
diff --git a/examples/14-function-calling.py b/examples/getting-started/07-function-calling.py
similarity index 100%
rename from examples/14-function-calling.py
rename to examples/getting-started/07-function-calling.py
diff --git a/examples/20c-persistent-context-anthropic.py b/examples/persistent-context/anthropic.py
similarity index 100%
rename from examples/20c-persistent-context-anthropic.py
rename to examples/persistent-context/anthropic.py
diff --git a/examples/20e-persistent-context-aws-nova-sonic.py b/examples/persistent-context/aws-nova-sonic.py
similarity index 100%
rename from examples/20e-persistent-context-aws-nova-sonic.py
rename to examples/persistent-context/aws-nova-sonic.py
diff --git a/examples/20d-persistent-context-gemini.py b/examples/persistent-context/gemini.py
similarity index 100%
rename from examples/20d-persistent-context-gemini.py
rename to examples/persistent-context/gemini.py
diff --git a/examples/20f-persistent-context-grok-realtime.py b/examples/persistent-context/grok-realtime.py
similarity index 100%
rename from examples/20f-persistent-context-grok-realtime.py
rename to examples/persistent-context/grok-realtime.py
diff --git a/examples/20b-persistent-context-openai-realtime-beta.py b/examples/persistent-context/openai-realtime-beta.py
similarity index 100%
rename from examples/20b-persistent-context-openai-realtime-beta.py
rename to examples/persistent-context/openai-realtime-beta.py
diff --git a/examples/20b-persistent-context-openai-realtime.py b/examples/persistent-context/openai-realtime.py
similarity index 100%
rename from examples/20b-persistent-context-openai-realtime.py
rename to examples/persistent-context/openai-realtime.py
diff --git a/examples/20a-persistent-context-openai-responses-http.py b/examples/persistent-context/openai-responses-http.py
similarity index 100%
rename from examples/20a-persistent-context-openai-responses-http.py
rename to examples/persistent-context/openai-responses-http.py
diff --git a/examples/20a-persistent-context-openai-responses.py b/examples/persistent-context/openai-responses.py
similarity index 100%
rename from examples/20a-persistent-context-openai-responses.py
rename to examples/persistent-context/openai-responses.py
diff --git a/examples/20a-persistent-context-openai.py b/examples/persistent-context/openai.py
similarity index 100%
rename from examples/20a-persistent-context-openai.py
rename to examples/persistent-context/openai.py
diff --git a/examples/40-aws-nova-sonic.py b/examples/realtime/aws-nova-sonic.py
similarity index 100%
rename from examples/40-aws-nova-sonic.py
rename to examples/realtime/aws-nova-sonic.py
diff --git a/examples/19a-azure-realtime-beta.py b/examples/realtime/azure-beta.py
similarity index 100%
rename from examples/19a-azure-realtime-beta.py
rename to examples/realtime/azure-beta.py
diff --git a/examples/19a-azure-realtime.py b/examples/realtime/azure.py
similarity index 100%
rename from examples/19a-azure-realtime.py
rename to examples/realtime/azure.py
diff --git a/examples/26f-gemini-live-files-api.py b/examples/realtime/gemini-live-files-api.py
similarity index 100%
rename from examples/26f-gemini-live-files-api.py
rename to examples/realtime/gemini-live-files-api.py
diff --git a/examples/26b-gemini-live-function-calling.py b/examples/realtime/gemini-live-function-calling.py
similarity index 100%
rename from examples/26b-gemini-live-function-calling.py
rename to examples/realtime/gemini-live-function-calling.py
diff --git a/examples/26e-gemini-live-google-search.py b/examples/realtime/gemini-live-google-search.py
similarity index 100%
rename from examples/26e-gemini-live-google-search.py
rename to examples/realtime/gemini-live-google-search.py
diff --git a/examples/26i-gemini-live-graceful-end.py b/examples/realtime/gemini-live-graceful-end.py
similarity index 100%
rename from examples/26i-gemini-live-graceful-end.py
rename to examples/realtime/gemini-live-graceful-end.py
diff --git a/examples/26g-gemini-live-groundingMetadata.py b/examples/realtime/gemini-live-grounding-metadata.py
similarity index 100%
rename from examples/26g-gemini-live-groundingMetadata.py
rename to examples/realtime/gemini-live-grounding-metadata.py
diff --git a/examples/26a-gemini-live-local-vad.py b/examples/realtime/gemini-live-local-vad.py
similarity index 100%
rename from examples/26a-gemini-live-local-vad.py
rename to examples/realtime/gemini-live-local-vad.py
diff --git a/examples/26h-gemini-live-vertex-function-calling.py b/examples/realtime/gemini-live-vertex-function-calling.py
similarity index 100%
rename from examples/26h-gemini-live-vertex-function-calling.py
rename to examples/realtime/gemini-live-vertex-function-calling.py
diff --git a/examples/26c-gemini-live-video.py b/examples/realtime/gemini-live-video.py
similarity index 100%
rename from examples/26c-gemini-live-video.py
rename to examples/realtime/gemini-live-video.py
diff --git a/examples/26-gemini-live.py b/examples/realtime/gemini-live.py
similarity index 100%
rename from examples/26-gemini-live.py
rename to examples/realtime/gemini-live.py
diff --git a/examples/51-grok-realtime.py b/examples/realtime/grok.py
similarity index 100%
rename from examples/51-grok-realtime.py
rename to examples/realtime/grok.py
diff --git a/examples/19b-openai-realtime-beta-text.py b/examples/realtime/openai-beta-text.py
similarity index 100%
rename from examples/19b-openai-realtime-beta-text.py
rename to examples/realtime/openai-beta-text.py
diff --git a/examples/19-openai-realtime-beta.py b/examples/realtime/openai-beta.py
similarity index 100%
rename from examples/19-openai-realtime-beta.py
rename to examples/realtime/openai-beta.py
diff --git a/examples/19c-openai-realtime-live-video.py b/examples/realtime/openai-live-video.py
similarity index 100%
rename from examples/19c-openai-realtime-live-video.py
rename to examples/realtime/openai-live-video.py
diff --git a/examples/19b-openai-realtime-text.py b/examples/realtime/openai-text.py
similarity index 100%
rename from examples/19b-openai-realtime-text.py
rename to examples/realtime/openai-text.py
diff --git a/examples/19-openai-realtime.py b/examples/realtime/openai.py
similarity index 100%
rename from examples/19-openai-realtime.py
rename to examples/realtime/openai.py
diff --git a/examples/50a-ultravox-realtime-text.py b/examples/realtime/ultravox-text.py
similarity index 100%
rename from examples/50a-ultravox-realtime-text.py
rename to examples/realtime/ultravox-text.py
diff --git a/examples/50-ultravox-realtime.py b/examples/realtime/ultravox.py
similarity index 100%
rename from examples/50-ultravox-realtime.py
rename to examples/realtime/ultravox.py
diff --git a/examples/14d-function-calling-anthropic-video.py b/examples/services/function-calling/anthropic-video.py
similarity index 100%
rename from examples/14d-function-calling-anthropic-video.py
rename to examples/services/function-calling/anthropic-video.py
diff --git a/examples/14a-function-calling-anthropic.py b/examples/services/function-calling/anthropic.py
similarity index 100%
rename from examples/14a-function-calling-anthropic.py
rename to examples/services/function-calling/anthropic.py
diff --git a/examples/14d-function-calling-aws-video.py b/examples/services/function-calling/aws-video.py
similarity index 100%
rename from examples/14d-function-calling-aws-video.py
rename to examples/services/function-calling/aws-video.py
diff --git a/examples/14r-function-calling-aws.py b/examples/services/function-calling/aws.py
similarity index 100%
rename from examples/14r-function-calling-aws.py
rename to examples/services/function-calling/aws.py
diff --git a/examples/14h-function-calling-azure.py b/examples/services/function-calling/azure.py
similarity index 100%
rename from examples/14h-function-calling-azure.py
rename to examples/services/function-calling/azure.py
diff --git a/examples/14k-function-calling-cerebras.py b/examples/services/function-calling/cerebras.py
similarity index 100%
rename from examples/14k-function-calling-cerebras.py
rename to examples/services/function-calling/cerebras.py
diff --git a/examples/14l-function-calling-deepseek.py b/examples/services/function-calling/deepseek.py
similarity index 100%
rename from examples/14l-function-calling-deepseek.py
rename to examples/services/function-calling/deepseek.py
diff --git a/examples/14t-function-calling-direct.py b/examples/services/function-calling/direct.py
similarity index 100%
rename from examples/14t-function-calling-direct.py
rename to examples/services/function-calling/direct.py
diff --git a/examples/14i-function-calling-fireworks.py b/examples/services/function-calling/fireworks.py
similarity index 100%
rename from examples/14i-function-calling-fireworks.py
rename to examples/services/function-calling/fireworks.py
diff --git a/examples/14o-function-calling-gemini-openai-format.py b/examples/services/function-calling/gemini-openai-format.py
similarity index 100%
rename from examples/14o-function-calling-gemini-openai-format.py
rename to examples/services/function-calling/gemini-openai-format.py
diff --git a/examples/14p-function-calling-gemini-vertex-ai.py b/examples/services/function-calling/google-vertex-ai.py
similarity index 100%
rename from examples/14p-function-calling-gemini-vertex-ai.py
rename to examples/services/function-calling/google-vertex-ai.py
diff --git a/examples/14d-function-calling-gemini-flash-video.py b/examples/services/function-calling/google-video.py
similarity index 100%
rename from examples/14d-function-calling-gemini-flash-video.py
rename to examples/services/function-calling/google-video.py
diff --git a/examples/14e-function-calling-google.py b/examples/services/function-calling/google.py
similarity index 100%
rename from examples/14e-function-calling-google.py
rename to examples/services/function-calling/google.py
diff --git a/examples/14g-function-calling-grok.py b/examples/services/function-calling/grok.py
similarity index 100%
rename from examples/14g-function-calling-grok.py
rename to examples/services/function-calling/grok.py
diff --git a/examples/14f-function-calling-groq.py b/examples/services/function-calling/groq.py
similarity index 100%
rename from examples/14f-function-calling-groq.py
rename to examples/services/function-calling/groq.py
diff --git a/examples/14w-function-calling-mistral.py b/examples/services/function-calling/mistral.py
similarity index 100%
rename from examples/14w-function-calling-mistral.py
rename to examples/services/function-calling/mistral.py
diff --git a/examples/14d-function-calling-moondream-video.py b/examples/services/function-calling/moondream-video.py
similarity index 100%
rename from examples/14d-function-calling-moondream-video.py
rename to examples/services/function-calling/moondream-video.py
diff --git a/examples/14v-function-calling-nebius.py b/examples/services/function-calling/nebius.py
similarity index 100%
rename from examples/14v-function-calling-nebius.py
rename to examples/services/function-calling/nebius.py
diff --git a/examples/14z-function-calling-novita.py b/examples/services/function-calling/novita.py
similarity index 100%
rename from examples/14z-function-calling-novita.py
rename to examples/services/function-calling/novita.py
diff --git a/examples/14j-function-calling-nvidia.py b/examples/services/function-calling/nvidia.py
similarity index 100%
rename from examples/14j-function-calling-nvidia.py
rename to examples/services/function-calling/nvidia.py
diff --git a/examples/14u-function-calling-ollama.py b/examples/services/function-calling/ollama.py
similarity index 100%
rename from examples/14u-function-calling-ollama.py
rename to examples/services/function-calling/ollama.py
diff --git a/examples/14-function-calling-openai-responses-http.py b/examples/services/function-calling/openai-responses-http.py
similarity index 100%
rename from examples/14-function-calling-openai-responses-http.py
rename to examples/services/function-calling/openai-responses-http.py
diff --git a/examples/14d-function-calling-openai-responses-video-http.py b/examples/services/function-calling/openai-responses-video-http.py
similarity index 100%
rename from examples/14d-function-calling-openai-responses-video-http.py
rename to examples/services/function-calling/openai-responses-video-http.py
diff --git a/examples/14d-function-calling-openai-responses-video.py b/examples/services/function-calling/openai-responses-video.py
similarity index 100%
rename from examples/14d-function-calling-openai-responses-video.py
rename to examples/services/function-calling/openai-responses-video.py
diff --git a/examples/14-function-calling-openai-responses.py b/examples/services/function-calling/openai-responses.py
similarity index 100%
rename from examples/14-function-calling-openai-responses.py
rename to examples/services/function-calling/openai-responses.py
diff --git a/examples/14d-function-calling-openai-video.py b/examples/services/function-calling/openai-video.py
similarity index 100%
rename from examples/14d-function-calling-openai-video.py
rename to examples/services/function-calling/openai-video.py
diff --git a/examples/14b-function-calling-openai.py b/examples/services/function-calling/openai.py
similarity index 100%
rename from examples/14b-function-calling-openai.py
rename to examples/services/function-calling/openai.py
diff --git a/examples/14m-function-calling-openrouter.py b/examples/services/function-calling/openrouter.py
similarity index 100%
rename from examples/14m-function-calling-openrouter.py
rename to examples/services/function-calling/openrouter.py
diff --git a/examples/14n-function-calling-perplexity.py b/examples/services/function-calling/perplexity.py
similarity index 100%
rename from examples/14n-function-calling-perplexity.py
rename to examples/services/function-calling/perplexity.py
diff --git a/examples/14q-function-calling-qwen.py b/examples/services/function-calling/qwen.py
similarity index 100%
rename from examples/14q-function-calling-qwen.py
rename to examples/services/function-calling/qwen.py
diff --git a/examples/14s-function-calling-sambanova.py b/examples/services/function-calling/sambanova.py
similarity index 100%
rename from examples/14s-function-calling-sambanova.py
rename to examples/services/function-calling/sambanova.py
diff --git a/examples/14y-function-calling-sarvam.py b/examples/services/function-calling/sarvam.py
similarity index 100%
rename from examples/14y-function-calling-sarvam.py
rename to examples/services/function-calling/sarvam.py
diff --git a/examples/14c-function-calling-together.py b/examples/services/function-calling/together.py
similarity index 100%
rename from examples/14c-function-calling-together.py
rename to examples/services/function-calling/together.py
diff --git a/examples/07zd-interruptible-aicoustics.py b/examples/services/speech/aicoustics.py
similarity index 100%
rename from examples/07zd-interruptible-aicoustics.py
rename to examples/services/speech/aicoustics.py
diff --git a/examples/07o-interruptible-assemblyai-turn-detection.py b/examples/services/speech/assemblyai-turn-detection.py
similarity index 100%
rename from examples/07o-interruptible-assemblyai-turn-detection.py
rename to examples/services/speech/assemblyai-turn-detection.py
diff --git a/examples/07o-interruptible-assemblyai.py b/examples/services/speech/assemblyai.py
similarity index 100%
rename from examples/07o-interruptible-assemblyai.py
rename to examples/services/speech/assemblyai.py
diff --git a/examples/07zc-interruptible-asyncai-http.py b/examples/services/speech/asyncai-http.py
similarity index 100%
rename from examples/07zc-interruptible-asyncai-http.py
rename to examples/services/speech/asyncai-http.py
diff --git a/examples/07zc-interruptible-asyncai.py b/examples/services/speech/asyncai.py
similarity index 100%
rename from examples/07zc-interruptible-asyncai.py
rename to examples/services/speech/asyncai.py
diff --git a/examples/07m-interruptible-aws-strands.py b/examples/services/speech/aws-strands.py
similarity index 100%
rename from examples/07m-interruptible-aws-strands.py
rename to examples/services/speech/aws-strands.py
diff --git a/examples/07m-interruptible-aws.py b/examples/services/speech/aws.py
similarity index 100%
rename from examples/07m-interruptible-aws.py
rename to examples/services/speech/aws.py
diff --git a/examples/07f-interruptible-azure-http.py b/examples/services/speech/azure-http.py
similarity index 100%
rename from examples/07f-interruptible-azure-http.py
rename to examples/services/speech/azure-http.py
diff --git a/examples/07f-interruptible-azure.py b/examples/services/speech/azure.py
similarity index 100%
rename from examples/07f-interruptible-azure.py
rename to examples/services/speech/azure.py
diff --git a/examples/07zg-interruptible-camb.py b/examples/services/speech/camb.py
similarity index 100%
rename from examples/07zg-interruptible-camb.py
rename to examples/services/speech/camb.py
diff --git a/examples/07-interruptible-cartesia-http.py b/examples/services/speech/cartesia-http.py
similarity index 100%
rename from examples/07-interruptible-cartesia-http.py
rename to examples/services/speech/cartesia-http.py
diff --git a/examples/06-listen-and-respond.py b/examples/services/speech/cartesia.py
similarity index 69%
rename from examples/06-listen-and-respond.py
rename to examples/services/speech/cartesia.py
index ec382681d..0489663e7 100644
--- a/examples/06-listen-and-respond.py
+++ b/examples/services/speech/cartesia.py
@@ -10,13 +10,7 @@ from dotenv import load_dotenv
from loguru import logger
from pipecat.audio.vad.silero import SileroVADAnalyzer
-from pipecat.frames.frames import Frame, LLMRunFrame, MetricsFrame
-from pipecat.metrics.metrics import (
- LLMUsageMetricsData,
- ProcessingMetricsData,
- TTFBMetricsData,
- TTSUsageMetricsData,
-)
+from pipecat.frames.frames import LLMRunFrame
from pipecat.pipeline.pipeline import Pipeline
from pipecat.pipeline.runner import PipelineRunner
from pipecat.pipeline.task import PipelineParams, PipelineTask
@@ -25,11 +19,10 @@ from pipecat.processors.aggregators.llm_response_universal import (
LLMContextAggregatorPair,
LLMUserAggregatorParams,
)
-from pipecat.processors.frame_processor import FrameDirection, FrameProcessor
from pipecat.runner.types import RunnerArguments
from pipecat.runner.utils import create_transport
+from pipecat.services.cartesia.stt import CartesiaSTTService
from pipecat.services.cartesia.tts import CartesiaTTSService
-from pipecat.services.deepgram.stt import DeepgramSTTService
from pipecat.services.openai.llm import OpenAILLMService
from pipecat.transports.base_transport import BaseTransport, TransportParams
from pipecat.transports.daily.transport import DailyParams
@@ -37,27 +30,6 @@ from pipecat.transports.websocket.fastapi import FastAPIWebsocketParams
load_dotenv(override=True)
-
-class MetricsLogger(FrameProcessor):
- async def process_frame(self, frame: Frame, direction: FrameDirection):
- await super().process_frame(frame, direction)
-
- if isinstance(frame, MetricsFrame):
- for d in frame.data:
- if isinstance(d, TTFBMetricsData):
- print(f"!!! MetricsFrame: {frame}, ttfb: {d.value}")
- elif isinstance(d, ProcessingMetricsData):
- print(f"!!! MetricsFrame: {frame}, processing: {d.value}")
- elif isinstance(d, LLMUsageMetricsData):
- tokens = d.value
- print(
- f"!!! MetricsFrame: {frame}, tokens: {tokens.prompt_tokens}, characters: {tokens.completion_tokens}"
- )
- elif isinstance(d, TTSUsageMetricsData):
- print(f"!!! MetricsFrame: {frame}, characters: {d.value}")
- await self.push_frame(frame, direction)
-
-
# We use lambdas to defer transport parameter creation until the transport
# type is selected at runtime.
transport_params = {
@@ -79,7 +51,7 @@ transport_params = {
async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
logger.info(f"Starting bot")
- stt = DeepgramSTTService(api_key=os.getenv("DEEPGRAM_API_KEY"))
+ stt = CartesiaSTTService(api_key=os.getenv("CARTESIA_API_KEY"))
tts = CartesiaTTSService(
api_key=os.getenv("CARTESIA_API_KEY"),
@@ -95,8 +67,6 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
),
)
- ml = MetricsLogger()
-
context = LLMContext()
user_aggregator, assistant_aggregator = LLMContextAggregatorPair(
context,
@@ -105,14 +75,13 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
pipeline = Pipeline(
[
- transport.input(),
+ transport.input(), # Transport user input
stt,
- user_aggregator,
- llm,
- tts,
- ml,
- transport.output(),
- assistant_aggregator,
+ user_aggregator, # User responses
+ llm, # LLM
+ tts, # TTS
+ transport.output(), # Transport bot output
+ assistant_aggregator, # Assistant spoken responses
]
)
@@ -140,6 +109,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
await task.cancel()
runner = PipelineRunner(handle_sigint=runner_args.handle_sigint)
+
await runner.run(task)
diff --git a/examples/07c-interruptible-deepgram-flux-sagemaker.py b/examples/services/speech/deepgram-flux-sagemaker.py
similarity index 100%
rename from examples/07c-interruptible-deepgram-flux-sagemaker.py
rename to examples/services/speech/deepgram-flux-sagemaker.py
diff --git a/examples/07c-interruptible-deepgram-flux.py b/examples/services/speech/deepgram-flux.py
similarity index 100%
rename from examples/07c-interruptible-deepgram-flux.py
rename to examples/services/speech/deepgram-flux.py
diff --git a/examples/07c-interruptible-deepgram-http.py b/examples/services/speech/deepgram-http.py
similarity index 100%
rename from examples/07c-interruptible-deepgram-http.py
rename to examples/services/speech/deepgram-http.py
diff --git a/examples/07c-interruptible-deepgram-sagemaker.py b/examples/services/speech/deepgram-sagemaker.py
similarity index 100%
rename from examples/07c-interruptible-deepgram-sagemaker.py
rename to examples/services/speech/deepgram-sagemaker.py
diff --git a/examples/07c-interruptible-deepgram-vad.py b/examples/services/speech/deepgram-vad.py
similarity index 100%
rename from examples/07c-interruptible-deepgram-vad.py
rename to examples/services/speech/deepgram-vad.py
diff --git a/examples/07c-interruptible-deepgram.py b/examples/services/speech/deepgram.py
similarity index 100%
rename from examples/07c-interruptible-deepgram.py
rename to examples/services/speech/deepgram.py
diff --git a/examples/07d-interruptible-elevenlabs-http.py b/examples/services/speech/elevenlabs-http.py
similarity index 100%
rename from examples/07d-interruptible-elevenlabs-http.py
rename to examples/services/speech/elevenlabs-http.py
diff --git a/examples/07d-interruptible-elevenlabs.py b/examples/services/speech/elevenlabs.py
similarity index 100%
rename from examples/07d-interruptible-elevenlabs.py
rename to examples/services/speech/elevenlabs.py
diff --git a/examples/07w-interruptible-fal.py b/examples/services/speech/fal.py
similarity index 100%
rename from examples/07w-interruptible-fal.py
rename to examples/services/speech/fal.py
diff --git a/examples/07t-interruptible-fish.py b/examples/services/speech/fish.py
similarity index 100%
rename from examples/07t-interruptible-fish.py
rename to examples/services/speech/fish.py
diff --git a/examples/07j-interruptible-gladia-vad.py b/examples/services/speech/gladia-vad.py
similarity index 100%
rename from examples/07j-interruptible-gladia-vad.py
rename to examples/services/speech/gladia-vad.py
diff --git a/examples/07j-interruptible-gladia.py b/examples/services/speech/gladia.py
similarity index 100%
rename from examples/07j-interruptible-gladia.py
rename to examples/services/speech/gladia.py
diff --git a/examples/07s-interruptible-google-audio-in.py b/examples/services/speech/google-audio-in.py
similarity index 100%
rename from examples/07s-interruptible-google-audio-in.py
rename to examples/services/speech/google-audio-in.py
diff --git a/examples/07n-interruptible-gemini.py b/examples/services/speech/google-gemini-tts.py
similarity index 100%
rename from examples/07n-interruptible-gemini.py
rename to examples/services/speech/google-gemini-tts.py
diff --git a/examples/07n-interruptible-google-http.py b/examples/services/speech/google-http.py
similarity index 100%
rename from examples/07n-interruptible-google-http.py
rename to examples/services/speech/google-http.py
diff --git a/examples/07n-interruptible-gemini-image.py b/examples/services/speech/google-image.py
similarity index 100%
rename from examples/07n-interruptible-gemini-image.py
rename to examples/services/speech/google-image.py
diff --git a/examples/07n-interruptible-google.py b/examples/services/speech/google.py
similarity index 100%
rename from examples/07n-interruptible-google.py
rename to examples/services/speech/google.py
diff --git a/examples/07zf-interruptible-gradium.py b/examples/services/speech/gradium.py
similarity index 100%
rename from examples/07zf-interruptible-gradium.py
rename to examples/services/speech/gradium.py
diff --git a/examples/07l-interruptible-groq.py b/examples/services/speech/groq.py
similarity index 100%
rename from examples/07l-interruptible-groq.py
rename to examples/services/speech/groq.py
diff --git a/examples/07ze-interruptible-hume.py b/examples/services/speech/hume.py
similarity index 100%
rename from examples/07ze-interruptible-hume.py
rename to examples/services/speech/hume.py
diff --git a/examples/07zb-interruptible-inworld-http.py b/examples/services/speech/inworld-http.py
similarity index 100%
rename from examples/07zb-interruptible-inworld-http.py
rename to examples/services/speech/inworld-http.py
diff --git a/examples/07zb-interruptible-inworld.py b/examples/services/speech/inworld.py
similarity index 100%
rename from examples/07zb-interruptible-inworld.py
rename to examples/services/speech/inworld.py
diff --git a/examples/07zj-interruptible-kokoro.py b/examples/services/speech/kokoro.py
similarity index 100%
rename from examples/07zj-interruptible-kokoro.py
rename to examples/services/speech/kokoro.py
diff --git a/examples/07p-interruptible-krisp-viva.py b/examples/services/speech/krisp-viva.py
similarity index 100%
rename from examples/07p-interruptible-krisp-viva.py
rename to examples/services/speech/krisp-viva.py
diff --git a/examples/07b-interruptible-langchain.py b/examples/services/speech/langchain.py
similarity index 100%
rename from examples/07b-interruptible-langchain.py
rename to examples/services/speech/langchain.py
diff --git a/examples/07k-interruptible-lmnt.py b/examples/services/speech/lmnt.py
similarity index 100%
rename from examples/07k-interruptible-lmnt.py
rename to examples/services/speech/lmnt.py
diff --git a/examples/07y-interruptible-minimax.py b/examples/services/speech/minimax.py
similarity index 100%
rename from examples/07y-interruptible-minimax.py
rename to examples/services/speech/minimax.py
diff --git a/examples/07v-interruptible-neuphonic-http.py b/examples/services/speech/neuphonic-http.py
similarity index 100%
rename from examples/07v-interruptible-neuphonic-http.py
rename to examples/services/speech/neuphonic-http.py
diff --git a/examples/07v-interruptible-neuphonic.py b/examples/services/speech/neuphonic.py
similarity index 100%
rename from examples/07v-interruptible-neuphonic.py
rename to examples/services/speech/neuphonic.py
diff --git a/examples/07r-interruptible-nvidia.py b/examples/services/speech/nvidia.py
similarity index 100%
rename from examples/07r-interruptible-nvidia.py
rename to examples/services/speech/nvidia.py
diff --git a/examples/07g-interruptible-openai-http.py b/examples/services/speech/openai-http.py
similarity index 100%
rename from examples/07g-interruptible-openai-http.py
rename to examples/services/speech/openai-http.py
diff --git a/examples/07-interruptible-openai-responses-http.py b/examples/services/speech/openai-responses-http.py
similarity index 100%
rename from examples/07-interruptible-openai-responses-http.py
rename to examples/services/speech/openai-responses-http.py
diff --git a/examples/07-interruptible-openai-responses.py b/examples/services/speech/openai-responses.py
similarity index 100%
rename from examples/07-interruptible-openai-responses.py
rename to examples/services/speech/openai-responses.py
diff --git a/examples/07g-interruptible-openai.py b/examples/services/speech/openai.py
similarity index 100%
rename from examples/07g-interruptible-openai.py
rename to examples/services/speech/openai.py
diff --git a/examples/07zi-interruptible-piper.py b/examples/services/speech/piper.py
similarity index 100%
rename from examples/07zi-interruptible-piper.py
rename to examples/services/speech/piper.py
diff --git a/examples/07zk-interruptible-resemble.py b/examples/services/speech/resemble.py
similarity index 100%
rename from examples/07zk-interruptible-resemble.py
rename to examples/services/speech/resemble.py
diff --git a/examples/07q-interruptible-rime-http.py b/examples/services/speech/rime-http.py
similarity index 100%
rename from examples/07q-interruptible-rime-http.py
rename to examples/services/speech/rime-http.py
diff --git a/examples/07q-interruptible-rime.py b/examples/services/speech/rime.py
similarity index 100%
rename from examples/07q-interruptible-rime.py
rename to examples/services/speech/rime.py
diff --git a/examples/07z-interruptible-sarvam-http.py b/examples/services/speech/sarvam-http.py
similarity index 100%
rename from examples/07z-interruptible-sarvam-http.py
rename to examples/services/speech/sarvam-http.py
diff --git a/examples/07z-interruptible-sarvam.py b/examples/services/speech/sarvam.py
similarity index 100%
rename from examples/07z-interruptible-sarvam.py
rename to examples/services/speech/sarvam.py
diff --git a/examples/07zl-interruptible-smallest.py b/examples/services/speech/smallest.py
similarity index 100%
rename from examples/07zl-interruptible-smallest.py
rename to examples/services/speech/smallest.py
diff --git a/examples/07za-interruptible-soniox.py b/examples/services/speech/soniox.py
similarity index 100%
rename from examples/07za-interruptible-soniox.py
rename to examples/services/speech/soniox.py
diff --git a/examples/07a-interruptible-speechmatics-vad.py b/examples/services/speech/speechmatics-vad.py
similarity index 100%
rename from examples/07a-interruptible-speechmatics-vad.py
rename to examples/services/speech/speechmatics-vad.py
diff --git a/examples/07a-interruptible-speechmatics.py b/examples/services/speech/speechmatics.py
similarity index 100%
rename from examples/07a-interruptible-speechmatics.py
rename to examples/services/speech/speechmatics.py
diff --git a/examples/07e-interruptible-xai.py b/examples/services/speech/xai.py
similarity index 100%
rename from examples/07e-interruptible-xai.py
rename to examples/services/speech/xai.py
diff --git a/examples/07i-interruptible-xtts.py b/examples/services/speech/xtts.py
similarity index 100%
rename from examples/07i-interruptible-xtts.py
rename to examples/services/speech/xtts.py
diff --git a/examples/39-mcp-stdio.py b/examples/thinking-and-mcp/mcp-stdio.py
similarity index 100%
rename from examples/39-mcp-stdio.py
rename to examples/thinking-and-mcp/mcp-stdio.py
diff --git a/examples/39b-mcp-streamable-http-gemini-live.py b/examples/thinking-and-mcp/mcp-streamable-http-gemini-live.py
similarity index 100%
rename from examples/39b-mcp-streamable-http-gemini-live.py
rename to examples/thinking-and-mcp/mcp-streamable-http-gemini-live.py
diff --git a/examples/39a-mcp-streamable-http.py b/examples/thinking-and-mcp/mcp-streamable-http.py
similarity index 100%
rename from examples/39a-mcp-streamable-http.py
rename to examples/thinking-and-mcp/mcp-streamable-http.py
diff --git a/examples/39c-multiple-mcp.py b/examples/thinking-and-mcp/multiple-mcp.py
similarity index 100%
rename from examples/39c-multiple-mcp.py
rename to examples/thinking-and-mcp/multiple-mcp.py
diff --git a/examples/49a-thinking-anthropic.py b/examples/thinking-and-mcp/thinking-anthropic.py
similarity index 100%
rename from examples/49a-thinking-anthropic.py
rename to examples/thinking-and-mcp/thinking-anthropic.py
diff --git a/examples/49c-thinking-functions-anthropic.py b/examples/thinking-and-mcp/thinking-functions-anthropic.py
similarity index 100%
rename from examples/49c-thinking-functions-anthropic.py
rename to examples/thinking-and-mcp/thinking-functions-anthropic.py
diff --git a/examples/49d-thinking-functions-google.py b/examples/thinking-and-mcp/thinking-functions-google.py
similarity index 100%
rename from examples/49d-thinking-functions-google.py
rename to examples/thinking-and-mcp/thinking-functions-google.py
diff --git a/examples/49b-thinking-google.py b/examples/thinking-and-mcp/thinking-google.py
similarity index 100%
rename from examples/49b-thinking-google.py
rename to examples/thinking-and-mcp/thinking-google.py
diff --git a/examples/13d-assemblyai-transcription.py b/examples/transcription/assemblyai.py
similarity index 100%
rename from examples/13d-assemblyai-transcription.py
rename to examples/transcription/assemblyai.py
diff --git a/examples/13j-azure-transcription.py b/examples/transcription/azure.py
similarity index 100%
rename from examples/13j-azure-transcription.py
rename to examples/transcription/azure.py
diff --git a/examples/13f-cartesia-transcription.py b/examples/transcription/cartesia.py
similarity index 100%
rename from examples/13f-cartesia-transcription.py
rename to examples/transcription/cartesia.py
diff --git a/examples/13b-deepgram-transcription.py b/examples/transcription/deepgram.py
similarity index 100%
rename from examples/13b-deepgram-transcription.py
rename to examples/transcription/deepgram.py
diff --git a/examples/13k-elevenlabs-transcription.py b/examples/transcription/elevenlabs.py
similarity index 100%
rename from examples/13k-elevenlabs-transcription.py
rename to examples/transcription/elevenlabs.py
diff --git a/examples/13c-gladia-transcription.py b/examples/transcription/gladia-transcription.py
similarity index 100%
rename from examples/13c-gladia-transcription.py
rename to examples/transcription/gladia-transcription.py
diff --git a/examples/13c-gladia-translation.py b/examples/transcription/gladia-translation.py
similarity index 100%
rename from examples/13c-gladia-translation.py
rename to examples/transcription/gladia-translation.py
diff --git a/examples/25-google-audio-in.py b/examples/transcription/google-llm.py
similarity index 100%
rename from examples/25-google-audio-in.py
rename to examples/transcription/google-llm.py
diff --git a/examples/13l-gradium-transcription.py b/examples/transcription/gradium.py
similarity index 100%
rename from examples/13l-gradium-transcription.py
rename to examples/transcription/gradium.py
diff --git a/examples/13m-openai-transcription.py b/examples/transcription/openai.py
similarity index 100%
rename from examples/13m-openai-transcription.py
rename to examples/transcription/openai.py
diff --git a/examples/13i-soniox-transcription.py b/examples/transcription/soniox.py
similarity index 100%
rename from examples/13i-soniox-transcription.py
rename to examples/transcription/soniox.py
diff --git a/examples/13h-speechmatics-transcription.py b/examples/transcription/speechmatics.py
similarity index 100%
rename from examples/13h-speechmatics-transcription.py
rename to examples/transcription/speechmatics.py
diff --git a/examples/13a-whisper-local.py b/examples/transcription/whisper-local.py
similarity index 100%
rename from examples/13a-whisper-local.py
rename to examples/transcription/whisper-local.py
diff --git a/examples/13e-whisper-mlx.py b/examples/transcription/whisper-mlx.py
similarity index 100%
rename from examples/13e-whisper-mlx.py
rename to examples/transcription/whisper-mlx.py
diff --git a/examples/13-whisper-transcription.py b/examples/transcription/whisper.py
similarity index 100%
rename from examples/13-whisper-transcription.py
rename to examples/transcription/whisper.py
diff --git a/examples/04a-transports-daily.py b/examples/transports/daily.py
similarity index 100%
rename from examples/04a-transports-daily.py
rename to examples/transports/daily.py
diff --git a/examples/04b-transports-livekit.py b/examples/transports/livekit.py
similarity index 100%
rename from examples/04b-transports-livekit.py
rename to examples/transports/livekit.py
diff --git a/examples/04-transports-small-webrtc.py b/examples/transports/small-webrtc.py
similarity index 100%
rename from examples/04-transports-small-webrtc.py
rename to examples/transports/small-webrtc.py
diff --git a/examples/17-detect-user-idle.py b/examples/turn-management/detect-user-idle.py
similarity index 100%
rename from examples/17-detect-user-idle.py
rename to examples/turn-management/detect-user-idle.py
diff --git a/examples/22-filter-incomplete-turns.py b/examples/turn-management/filter-incomplete-turns.py
similarity index 100%
rename from examples/22-filter-incomplete-turns.py
rename to examples/turn-management/filter-incomplete-turns.py
diff --git a/examples/42-interruption-config.py b/examples/turn-management/interruption-config.py
similarity index 100%
rename from examples/42-interruption-config.py
rename to examples/turn-management/interruption-config.py
diff --git a/examples/38a-smart-turn-local-coreml.py b/examples/turn-management/smart-turn-local-coreml.py
similarity index 100%
rename from examples/38a-smart-turn-local-coreml.py
rename to examples/turn-management/smart-turn-local-coreml.py
diff --git a/examples/38b-smart-turn-local.py b/examples/turn-management/smart-turn-local.py
similarity index 100%
rename from examples/38b-smart-turn-local.py
rename to examples/turn-management/smart-turn-local.py
diff --git a/examples/29-turn-tracking-observer.py b/examples/turn-management/turn-tracking-observer.py
similarity index 100%
rename from examples/29-turn-tracking-observer.py
rename to examples/turn-management/turn-tracking-observer.py
diff --git a/examples/28-user-assistant-turns.py b/examples/turn-management/user-assistant-turns.py
similarity index 100%
rename from examples/28-user-assistant-turns.py
rename to examples/turn-management/user-assistant-turns.py
diff --git a/examples/24-user-mute-strategy.py b/examples/turn-management/user-mute-strategy.py
similarity index 100%
rename from examples/24-user-mute-strategy.py
rename to examples/turn-management/user-mute-strategy.py
diff --git a/examples/55zj-update-settings-anthropic-llm.py b/examples/update-settings/llm/anthropic.py
similarity index 100%
rename from examples/55zj-update-settings-anthropic-llm.py
rename to examples/update-settings/llm/anthropic.py
diff --git a/examples/55zp-update-settings-aws-bedrock-llm.py b/examples/update-settings/llm/aws-bedrock.py
similarity index 100%
rename from examples/55zp-update-settings-aws-bedrock-llm.py
rename to examples/update-settings/llm/aws-bedrock.py
diff --git a/examples/55zzk-update-settings-aws-nova-sonic-llm.py b/examples/update-settings/llm/aws-nova-sonic.py
similarity index 100%
rename from examples/55zzk-update-settings-aws-nova-sonic-llm.py
rename to examples/update-settings/llm/aws-nova-sonic.py
diff --git a/examples/55zl-update-settings-azure-realtime.py b/examples/update-settings/llm/azure-realtime.py
similarity index 100%
rename from examples/55zl-update-settings-azure-realtime.py
rename to examples/update-settings/llm/azure-realtime.py
diff --git a/examples/55zi-update-settings-azure-llm.py b/examples/update-settings/llm/azure.py
similarity index 100%
rename from examples/55zi-update-settings-azure-llm.py
rename to examples/update-settings/llm/azure.py
diff --git a/examples/55zx-update-settings-cerebras-llm.py b/examples/update-settings/llm/cerebras.py
similarity index 100%
rename from examples/55zx-update-settings-cerebras-llm.py
rename to examples/update-settings/llm/cerebras.py
diff --git a/examples/55zy-update-settings-deepseek-llm.py b/examples/update-settings/llm/deepseek.py
similarity index 100%
rename from examples/55zy-update-settings-deepseek-llm.py
rename to examples/update-settings/llm/deepseek.py
diff --git a/examples/55zz-update-settings-fireworks-llm.py b/examples/update-settings/llm/fireworks.py
similarity index 100%
rename from examples/55zz-update-settings-fireworks-llm.py
rename to examples/update-settings/llm/fireworks.py
diff --git a/examples/55zm-update-settings-gemini-live-vertex.py b/examples/update-settings/llm/gemini-live-vertex.py
similarity index 100%
rename from examples/55zm-update-settings-gemini-live-vertex.py
rename to examples/update-settings/llm/gemini-live-vertex.py
diff --git a/examples/55zm-update-settings-gemini-live.py b/examples/update-settings/llm/gemini-live.py
similarity index 100%
rename from examples/55zm-update-settings-gemini-live.py
rename to examples/update-settings/llm/gemini-live.py
diff --git a/examples/55zk-update-settings-google-vertex-llm.py b/examples/update-settings/llm/google-vertex.py
similarity index 100%
rename from examples/55zk-update-settings-google-vertex-llm.py
rename to examples/update-settings/llm/google-vertex.py
diff --git a/examples/55zk-update-settings-google-llm.py b/examples/update-settings/llm/google.py
similarity index 100%
rename from examples/55zk-update-settings-google-llm.py
rename to examples/update-settings/llm/google.py
diff --git a/examples/55zo-update-settings-grok-realtime.py b/examples/update-settings/llm/grok-realtime.py
similarity index 100%
rename from examples/55zo-update-settings-grok-realtime.py
rename to examples/update-settings/llm/grok-realtime.py
diff --git a/examples/55zza-update-settings-grok-llm.py b/examples/update-settings/llm/grok.py
similarity index 100%
rename from examples/55zza-update-settings-grok-llm.py
rename to examples/update-settings/llm/grok.py
diff --git a/examples/55zzb-update-settings-groq-llm.py b/examples/update-settings/llm/groq.py
similarity index 100%
rename from examples/55zzb-update-settings-groq-llm.py
rename to examples/update-settings/llm/groq.py
diff --git a/examples/55zzc-update-settings-mistral-llm.py b/examples/update-settings/llm/mistral.py
similarity index 100%
rename from examples/55zzc-update-settings-mistral-llm.py
rename to examples/update-settings/llm/mistral.py
diff --git a/examples/55zzd-update-settings-nvidia-llm.py b/examples/update-settings/llm/nvidia.py
similarity index 100%
rename from examples/55zzd-update-settings-nvidia-llm.py
rename to examples/update-settings/llm/nvidia.py
diff --git a/examples/55zze-update-settings-ollama-llm.py b/examples/update-settings/llm/ollama.py
similarity index 100%
rename from examples/55zze-update-settings-ollama-llm.py
rename to examples/update-settings/llm/ollama.py
diff --git a/examples/55zl-update-settings-openai-realtime.py b/examples/update-settings/llm/openai-realtime.py
similarity index 100%
rename from examples/55zl-update-settings-openai-realtime.py
rename to examples/update-settings/llm/openai-realtime.py
diff --git a/examples/55zi-update-settings-openai-responses-http-llm.py b/examples/update-settings/llm/openai-responses-http.py
similarity index 100%
rename from examples/55zi-update-settings-openai-responses-http-llm.py
rename to examples/update-settings/llm/openai-responses-http.py
diff --git a/examples/55zi-update-settings-openai-responses-llm.py b/examples/update-settings/llm/openai-responses.py
similarity index 100%
rename from examples/55zi-update-settings-openai-responses-llm.py
rename to examples/update-settings/llm/openai-responses.py
diff --git a/examples/55zi-update-settings-openai-llm.py b/examples/update-settings/llm/openai.py
similarity index 100%
rename from examples/55zi-update-settings-openai-llm.py
rename to examples/update-settings/llm/openai.py
diff --git a/examples/55zzf-update-settings-openrouter-llm.py b/examples/update-settings/llm/openrouter.py
similarity index 100%
rename from examples/55zzf-update-settings-openrouter-llm.py
rename to examples/update-settings/llm/openrouter.py
diff --git a/examples/55zzg-update-settings-perplexity-llm.py b/examples/update-settings/llm/perplexity.py
similarity index 100%
rename from examples/55zzg-update-settings-perplexity-llm.py
rename to examples/update-settings/llm/perplexity.py
diff --git a/examples/55zzh-update-settings-qwen-llm.py b/examples/update-settings/llm/qwen.py
similarity index 100%
rename from examples/55zzh-update-settings-qwen-llm.py
rename to examples/update-settings/llm/qwen.py
diff --git a/examples/55zzi-update-settings-sambanova-llm.py b/examples/update-settings/llm/sambanova.py
similarity index 100%
rename from examples/55zzi-update-settings-sambanova-llm.py
rename to examples/update-settings/llm/sambanova.py
diff --git a/examples/55zzq-update-settings-sarvam-llm.py b/examples/update-settings/llm/sarvam.py
similarity index 100%
rename from examples/55zzq-update-settings-sarvam-llm.py
rename to examples/update-settings/llm/sarvam.py
diff --git a/examples/55zzj-update-settings-together-llm.py b/examples/update-settings/llm/together.py
similarity index 100%
rename from examples/55zzj-update-settings-together-llm.py
rename to examples/update-settings/llm/together.py
diff --git a/examples/55zn-update-settings-ultravox-realtime.py b/examples/update-settings/llm/ultravox-realtime.py
similarity index 100%
rename from examples/55zn-update-settings-ultravox-realtime.py
rename to examples/update-settings/llm/ultravox-realtime.py
diff --git a/examples/55d-update-settings-assemblyai-stt.py b/examples/update-settings/stt/assemblyai.py
similarity index 100%
rename from examples/55d-update-settings-assemblyai-stt.py
rename to examples/update-settings/stt/assemblyai.py
diff --git a/examples/55l-update-settings-aws-transcribe-stt.py b/examples/update-settings/stt/aws-transcribe.py
similarity index 100%
rename from examples/55l-update-settings-aws-transcribe-stt.py
rename to examples/update-settings/stt/aws-transcribe.py
diff --git a/examples/55b-update-settings-azure-stt.py b/examples/update-settings/stt/azure.py
similarity index 100%
rename from examples/55b-update-settings-azure-stt.py
rename to examples/update-settings/stt/azure.py
diff --git a/examples/55m-update-settings-cartesia-stt.py b/examples/update-settings/stt/cartesia.py
similarity index 100%
rename from examples/55m-update-settings-cartesia-stt.py
rename to examples/update-settings/stt/cartesia.py
diff --git a/examples/55a-update-settings-deepgram-flux-stt.py b/examples/update-settings/stt/deepgram-flux.py
similarity index 100%
rename from examples/55a-update-settings-deepgram-flux-stt.py
rename to examples/update-settings/stt/deepgram-flux.py
diff --git a/examples/55a-update-settings-deepgram-sagemaker-stt.py b/examples/update-settings/stt/deepgram-sagemaker.py
similarity index 100%
rename from examples/55a-update-settings-deepgram-sagemaker-stt.py
rename to examples/update-settings/stt/deepgram-sagemaker.py
diff --git a/examples/55a-update-settings-deepgram-stt.py b/examples/update-settings/stt/deepgram.py
similarity index 100%
rename from examples/55a-update-settings-deepgram-stt.py
rename to examples/update-settings/stt/deepgram.py
diff --git a/examples/55f-update-settings-elevenlabs-realtime-stt.py b/examples/update-settings/stt/elevenlabs-realtime.py
similarity index 100%
rename from examples/55f-update-settings-elevenlabs-realtime-stt.py
rename to examples/update-settings/stt/elevenlabs-realtime.py
diff --git a/examples/55g-update-settings-elevenlabs-stt.py b/examples/update-settings/stt/elevenlabs.py
similarity index 100%
rename from examples/55g-update-settings-elevenlabs-stt.py
rename to examples/update-settings/stt/elevenlabs.py
diff --git a/examples/55zq-update-settings-fal-stt.py b/examples/update-settings/stt/fal.py
similarity index 100%
rename from examples/55zq-update-settings-fal-stt.py
rename to examples/update-settings/stt/fal.py
diff --git a/examples/55e-update-settings-gladia-stt.py b/examples/update-settings/stt/gladia.py
similarity index 100%
rename from examples/55e-update-settings-gladia-stt.py
rename to examples/update-settings/stt/gladia.py
diff --git a/examples/55c-update-settings-google-stt.py b/examples/update-settings/stt/google.py
similarity index 100%
rename from examples/55c-update-settings-google-stt.py
rename to examples/update-settings/stt/google.py
diff --git a/examples/55zr-update-settings-gradium-stt.py b/examples/update-settings/stt/gradium.py
similarity index 100%
rename from examples/55zr-update-settings-gradium-stt.py
rename to examples/update-settings/stt/gradium.py
diff --git a/examples/55zzn-update-settings-groq-stt.py b/examples/update-settings/stt/groq.py
similarity index 100%
rename from examples/55zzn-update-settings-groq-stt.py
rename to examples/update-settings/stt/groq.py
diff --git a/examples/55zt-update-settings-nvidia-segmented-stt.py b/examples/update-settings/stt/nvidia-segmented.py
similarity index 100%
rename from examples/55zt-update-settings-nvidia-segmented-stt.py
rename to examples/update-settings/stt/nvidia-segmented.py
diff --git a/examples/55zt-update-settings-nvidia-stt.py b/examples/update-settings/stt/nvidia.py
similarity index 100%
rename from examples/55zt-update-settings-nvidia-stt.py
rename to examples/update-settings/stt/nvidia.py
diff --git a/examples/55zu-update-settings-openai-realtime-stt.py b/examples/update-settings/stt/openai-realtime.py
similarity index 100%
rename from examples/55zu-update-settings-openai-realtime-stt.py
rename to examples/update-settings/stt/openai-realtime.py
diff --git a/examples/55j-update-settings-sarvam-stt.py b/examples/update-settings/stt/sarvam.py
similarity index 100%
rename from examples/55j-update-settings-sarvam-stt.py
rename to examples/update-settings/stt/sarvam.py
diff --git a/examples/55k-update-settings-soniox-stt.py b/examples/update-settings/stt/soniox.py
similarity index 100%
rename from examples/55k-update-settings-soniox-stt.py
rename to examples/update-settings/stt/soniox.py
diff --git a/examples/55h-update-settings-speechmatics-stt.py b/examples/update-settings/stt/speechmatics.py
similarity index 100%
rename from examples/55h-update-settings-speechmatics-stt.py
rename to examples/update-settings/stt/speechmatics.py
diff --git a/examples/55i-update-settings-whisper-api-stt.py b/examples/update-settings/stt/whisper-api.py
similarity index 100%
rename from examples/55i-update-settings-whisper-api-stt.py
rename to examples/update-settings/stt/whisper-api.py
diff --git a/examples/55zs-update-settings-whisper-mlx-stt.py b/examples/update-settings/stt/whisper-mlx.py
similarity index 100%
rename from examples/55zs-update-settings-whisper-mlx-stt.py
rename to examples/update-settings/stt/whisper-mlx.py
diff --git a/examples/55zs-update-settings-whisper-stt.py b/examples/update-settings/stt/whisper.py
similarity index 100%
rename from examples/55zs-update-settings-whisper-stt.py
rename to examples/update-settings/stt/whisper.py
diff --git a/examples/55zv-update-settings-asyncai-http-tts.py b/examples/update-settings/tts/asyncai-http.py
similarity index 100%
rename from examples/55zv-update-settings-asyncai-http-tts.py
rename to examples/update-settings/tts/asyncai-http.py
diff --git a/examples/55zv-update-settings-asyncai-tts.py b/examples/update-settings/tts/asyncai.py
similarity index 100%
rename from examples/55zv-update-settings-asyncai-tts.py
rename to examples/update-settings/tts/asyncai.py
diff --git a/examples/55zd-update-settings-aws-polly-tts.py b/examples/update-settings/tts/aws-polly.py
similarity index 100%
rename from examples/55zd-update-settings-aws-polly-tts.py
rename to examples/update-settings/tts/aws-polly.py
diff --git a/examples/55r-update-settings-azure-http-tts.py b/examples/update-settings/tts/azure-http.py
similarity index 100%
rename from examples/55r-update-settings-azure-http-tts.py
rename to examples/update-settings/tts/azure-http.py
diff --git a/examples/55r-update-settings-azure-tts.py b/examples/update-settings/tts/azure.py
similarity index 100%
rename from examples/55r-update-settings-azure-tts.py
rename to examples/update-settings/tts/azure.py
diff --git a/examples/55zf-update-settings-camb-tts.py b/examples/update-settings/tts/camb.py
similarity index 100%
rename from examples/55zf-update-settings-camb-tts.py
rename to examples/update-settings/tts/camb.py
diff --git a/examples/55n-update-settings-cartesia-http-tts.py b/examples/update-settings/tts/cartesia-http.py
similarity index 100%
rename from examples/55n-update-settings-cartesia-http-tts.py
rename to examples/update-settings/tts/cartesia-http.py
diff --git a/examples/55n-update-settings-cartesia-tts.py b/examples/update-settings/tts/cartesia.py
similarity index 100%
rename from examples/55n-update-settings-cartesia-tts.py
rename to examples/update-settings/tts/cartesia.py
diff --git a/examples/55q-update-settings-deepgram-http-tts.py b/examples/update-settings/tts/deepgram-http.py
similarity index 100%
rename from examples/55q-update-settings-deepgram-http-tts.py
rename to examples/update-settings/tts/deepgram-http.py
diff --git a/examples/55q-update-settings-deepgram-sagemaker-tts.py b/examples/update-settings/tts/deepgram-sagemaker.py
similarity index 100%
rename from examples/55q-update-settings-deepgram-sagemaker-tts.py
rename to examples/update-settings/tts/deepgram-sagemaker.py
diff --git a/examples/55q-update-settings-deepgram-tts.py b/examples/update-settings/tts/deepgram.py
similarity index 100%
rename from examples/55q-update-settings-deepgram-tts.py
rename to examples/update-settings/tts/deepgram.py
diff --git a/examples/55o-update-settings-elevenlabs-http-tts.py b/examples/update-settings/tts/elevenlabs-http.py
similarity index 100%
rename from examples/55o-update-settings-elevenlabs-http-tts.py
rename to examples/update-settings/tts/elevenlabs-http.py
diff --git a/examples/55o-update-settings-elevenlabs-tts.py b/examples/update-settings/tts/elevenlabs.py
similarity index 100%
rename from examples/55o-update-settings-elevenlabs-tts.py
rename to examples/update-settings/tts/elevenlabs.py
diff --git a/examples/55w-update-settings-fish-tts.py b/examples/update-settings/tts/fish.py
similarity index 100%
rename from examples/55w-update-settings-fish-tts.py
rename to examples/update-settings/tts/fish.py
diff --git a/examples/55zc-update-settings-gemini-tts.py b/examples/update-settings/tts/gemini.py
similarity index 100%
rename from examples/55zc-update-settings-gemini-tts.py
rename to examples/update-settings/tts/gemini.py
diff --git a/examples/55s-update-settings-google-http-tts.py b/examples/update-settings/tts/google-http.py
similarity index 100%
rename from examples/55s-update-settings-google-http-tts.py
rename to examples/update-settings/tts/google-http.py
diff --git a/examples/55s-update-settings-google-stream-tts.py b/examples/update-settings/tts/google-stream.py
similarity index 100%
rename from examples/55s-update-settings-google-stream-tts.py
rename to examples/update-settings/tts/google-stream.py
diff --git a/examples/55zw-update-settings-gradium-tts.py b/examples/update-settings/tts/gradium.py
similarity index 100%
rename from examples/55zw-update-settings-gradium-tts.py
rename to examples/update-settings/tts/gradium.py
diff --git a/examples/55y-update-settings-groq-tts.py b/examples/update-settings/tts/groq.py
similarity index 100%
rename from examples/55y-update-settings-groq-tts.py
rename to examples/update-settings/tts/groq.py
diff --git a/examples/55z-update-settings-hume-tts.py b/examples/update-settings/tts/hume.py
similarity index 100%
rename from examples/55z-update-settings-hume-tts.py
rename to examples/update-settings/tts/hume.py
diff --git a/examples/55zb-update-settings-inworld-http-tts.py b/examples/update-settings/tts/inworld-http.py
similarity index 100%
rename from examples/55zb-update-settings-inworld-http-tts.py
rename to examples/update-settings/tts/inworld-http.py
diff --git a/examples/55zb-update-settings-inworld-tts.py b/examples/update-settings/tts/inworld.py
similarity index 100%
rename from examples/55zb-update-settings-inworld-tts.py
rename to examples/update-settings/tts/inworld.py
diff --git a/examples/55zg-update-settings-kokoro-tts.py b/examples/update-settings/tts/kokoro.py
similarity index 100%
rename from examples/55zg-update-settings-kokoro-tts.py
rename to examples/update-settings/tts/kokoro.py
diff --git a/examples/55v-update-settings-lmnt-tts.py b/examples/update-settings/tts/lmnt.py
similarity index 100%
rename from examples/55v-update-settings-lmnt-tts.py
rename to examples/update-settings/tts/lmnt.py
diff --git a/examples/55x-update-settings-minimax-tts.py b/examples/update-settings/tts/minimax.py
similarity index 100%
rename from examples/55x-update-settings-minimax-tts.py
rename to examples/update-settings/tts/minimax.py
diff --git a/examples/55za-update-settings-neuphonic-http-tts.py b/examples/update-settings/tts/neuphonic-http.py
similarity index 100%
rename from examples/55za-update-settings-neuphonic-http-tts.py
rename to examples/update-settings/tts/neuphonic-http.py
diff --git a/examples/55za-update-settings-neuphonic-tts.py b/examples/update-settings/tts/neuphonic.py
similarity index 100%
rename from examples/55za-update-settings-neuphonic-tts.py
rename to examples/update-settings/tts/neuphonic.py
diff --git a/examples/55zzl-update-settings-nvidia-tts.py b/examples/update-settings/tts/nvidia.py
similarity index 100%
rename from examples/55zzl-update-settings-nvidia-tts.py
rename to examples/update-settings/tts/nvidia.py
diff --git a/examples/55p-update-settings-openai-tts.py b/examples/update-settings/tts/openai.py
similarity index 100%
rename from examples/55p-update-settings-openai-tts.py
rename to examples/update-settings/tts/openai.py
diff --git a/examples/55t-update-settings-piper-http-tts.py b/examples/update-settings/tts/piper-http.py
similarity index 100%
rename from examples/55t-update-settings-piper-http-tts.py
rename to examples/update-settings/tts/piper-http.py
diff --git a/examples/55t-update-settings-piper-tts.py b/examples/update-settings/tts/piper.py
similarity index 100%
rename from examples/55t-update-settings-piper-tts.py
rename to examples/update-settings/tts/piper.py
diff --git a/examples/55zh-update-settings-resembleai-tts.py b/examples/update-settings/tts/resembleai.py
similarity index 100%
rename from examples/55zh-update-settings-resembleai-tts.py
rename to examples/update-settings/tts/resembleai.py
diff --git a/examples/55u-update-settings-rime-http-tts.py b/examples/update-settings/tts/rime-http.py
similarity index 100%
rename from examples/55u-update-settings-rime-http-tts.py
rename to examples/update-settings/tts/rime-http.py
diff --git a/examples/55u-update-settings-rime-tts.py b/examples/update-settings/tts/rime.py
similarity index 100%
rename from examples/55u-update-settings-rime-tts.py
rename to examples/update-settings/tts/rime.py
diff --git a/examples/55ze-update-settings-sarvam-http-tts.py b/examples/update-settings/tts/sarvam-http.py
similarity index 100%
rename from examples/55ze-update-settings-sarvam-http-tts.py
rename to examples/update-settings/tts/sarvam-http.py
diff --git a/examples/55ze-update-settings-sarvam-tts.py b/examples/update-settings/tts/sarvam.py
similarity index 100%
rename from examples/55ze-update-settings-sarvam-tts.py
rename to examples/update-settings/tts/sarvam.py
diff --git a/examples/55zzm-update-settings-speechmatics-tts.py b/examples/update-settings/tts/speechmatics.py
similarity index 100%
rename from examples/55zzm-update-settings-speechmatics-tts.py
rename to examples/update-settings/tts/speechmatics.py
diff --git a/examples/55zzp-update-settings-xtts-tts.py b/examples/update-settings/tts/xtts.py
similarity index 100%
rename from examples/55zzp-update-settings-xtts-tts.py
rename to examples/update-settings/tts/xtts.py
diff --git a/examples/43-heygen-transport.py b/examples/video-avatar/heygen-transport.py
similarity index 100%
rename from examples/43-heygen-transport.py
rename to examples/video-avatar/heygen-transport.py
diff --git a/examples/43a-heygen-video-service.py b/examples/video-avatar/heygen-video-service.py
similarity index 100%
rename from examples/43a-heygen-video-service.py
rename to examples/video-avatar/heygen-video-service.py
diff --git a/examples/56-lemonslice-transport.py b/examples/video-avatar/lemonslice-transport.py
similarity index 100%
rename from examples/56-lemonslice-transport.py
rename to examples/video-avatar/lemonslice-transport.py
diff --git a/examples/27-simli-layer.py b/examples/video-avatar/simli-layer.py
similarity index 100%
rename from examples/27-simli-layer.py
rename to examples/video-avatar/simli-layer.py
diff --git a/examples/21-tavus-transport.py b/examples/video-avatar/tavus-transport.py
similarity index 100%
rename from examples/21-tavus-transport.py
rename to examples/video-avatar/tavus-transport.py
diff --git a/examples/21a-tavus-video-service.py b/examples/video-avatar/tavus-video-service.py
similarity index 100%
rename from examples/21a-tavus-video-service.py
rename to examples/video-avatar/tavus-video-service.py
diff --git a/examples/57-custom-video-track.py b/examples/video-processing/custom-video-track.py
similarity index 100%
rename from examples/57-custom-video-track.py
rename to examples/video-processing/custom-video-track.py
diff --git a/examples/18-gstreamer-filesrc.py b/examples/video-processing/gstreamer-filesrc.py
similarity index 100%
rename from examples/18-gstreamer-filesrc.py
rename to examples/video-processing/gstreamer-filesrc.py
diff --git a/examples/18a-gstreamer-videotestsrc.py b/examples/video-processing/gstreamer-videotestsrc.py
similarity index 100%
rename from examples/18a-gstreamer-videotestsrc.py
rename to examples/video-processing/gstreamer-videotestsrc.py
diff --git a/examples/09a-local-mirror.py b/examples/video-processing/local-mirror.py
similarity index 100%
rename from examples/09a-local-mirror.py
rename to examples/video-processing/local-mirror.py
diff --git a/examples/09-mirror.py b/examples/video-processing/mirror.py
similarity index 100%
rename from examples/09-mirror.py
rename to examples/video-processing/mirror.py
diff --git a/examples/46-video-processing.py b/examples/video-processing/video-processing.py
similarity index 100%
rename from examples/46-video-processing.py
rename to examples/video-processing/video-processing.py
diff --git a/examples/12a-describe-image-anthropic.py b/examples/vision/anthropic.py
similarity index 100%
rename from examples/12a-describe-image-anthropic.py
rename to examples/vision/anthropic.py
diff --git a/examples/12b-describe-image-aws.py b/examples/vision/aws.py
similarity index 100%
rename from examples/12b-describe-image-aws.py
rename to examples/vision/aws.py
diff --git a/examples/12c-describe-image-gemini-flash.py b/examples/vision/gemini-flash.py
similarity index 100%
rename from examples/12c-describe-image-gemini-flash.py
rename to examples/vision/gemini-flash.py
diff --git a/examples/12d-describe-image-moondream.py b/examples/vision/moondream.py
similarity index 100%
rename from examples/12d-describe-image-moondream.py
rename to examples/vision/moondream.py
diff --git a/examples/12-describe-image-openai-responses-http.py b/examples/vision/openai-responses-http.py
similarity index 100%
rename from examples/12-describe-image-openai-responses-http.py
rename to examples/vision/openai-responses-http.py
diff --git a/examples/12-describe-image-openai-responses.py b/examples/vision/openai-responses.py
similarity index 100%
rename from examples/12-describe-image-openai-responses.py
rename to examples/vision/openai-responses.py
diff --git a/examples/12-describe-image-openai.py b/examples/vision/openai.py
similarity index 100%
rename from examples/12-describe-image-openai.py
rename to examples/vision/openai.py
diff --git a/scripts/evals/run-release-evals.py b/scripts/evals/run-release-evals.py
index 92e872ac2..3c540ff87 100644
--- a/scripts/evals/run-release-evals.py
+++ b/scripts/evals/run-release-evals.py
@@ -96,214 +96,175 @@ EVAL_COMPLETE_TURN = EvalConfig(
)
-TESTS_07 = [
- # 07 series
- ("07-interruptible.py", EVAL_SIMPLE_MATH),
- ("07-interruptible-cartesia-http.py", EVAL_SIMPLE_MATH),
- ("07a-interruptible-speechmatics.py", EVAL_SIMPLE_MATH),
- ("07a-interruptible-speechmatics-vad.py", EVAL_SIMPLE_MATH),
- ("07b-interruptible-langchain.py", EVAL_SIMPLE_MATH),
- ("07c-interruptible-deepgram.py", EVAL_SIMPLE_MATH),
- ("07c-interruptible-deepgram-flux.py", EVAL_SIMPLE_MATH),
- ("07c-interruptible-deepgram-http.py", EVAL_SIMPLE_MATH),
- ("07d-interruptible-elevenlabs.py", EVAL_SIMPLE_MATH),
- ("07d-interruptible-elevenlabs-http.py", EVAL_SIMPLE_MATH),
- ("07e-interruptible-xai.py", EVAL_SIMPLE_MATH),
- ("07f-interruptible-azure.py", EVAL_SIMPLE_MATH),
- ("07f-interruptible-azure-http.py", EVAL_SIMPLE_MATH),
- ("07g-interruptible-openai.py", EVAL_SIMPLE_MATH),
- ("07g-interruptible-openai-http.py", EVAL_SIMPLE_MATH),
- ("07j-interruptible-gladia.py", EVAL_SIMPLE_MATH),
- ("07j-interruptible-gladia-vad.py", EVAL_SIMPLE_MATH),
- ("07k-interruptible-lmnt.py", EVAL_SIMPLE_MATH),
- ("07l-interruptible-groq.py", EVAL_SIMPLE_MATH),
- ("07m-interruptible-aws.py", EVAL_SIMPLE_MATH),
- ("07m-interruptible-aws-strands.py", EVAL_WEATHER),
- ("07n-interruptible-gemini.py", EVAL_SIMPLE_MATH),
- ("07n-interruptible-google.py", EVAL_SIMPLE_MATH),
- ("07n-interruptible-google-http.py", EVAL_SIMPLE_MATH),
- ("07o-interruptible-assemblyai.py", EVAL_SIMPLE_MATH),
- ("07p-interruptible-krisp-viva.py", EVAL_SIMPLE_MATH),
- ("07q-interruptible-rime.py", EVAL_SIMPLE_MATH),
- ("07q-interruptible-rime-http.py", EVAL_SIMPLE_MATH),
- ("07r-interruptible-nvidia.py", EVAL_SIMPLE_MATH),
- ("07s-interruptible-google-audio-in.py", EVAL_SIMPLE_MATH),
- ("07t-interruptible-fish.py", EVAL_SIMPLE_MATH),
- ("07v-interruptible-neuphonic.py", EVAL_SIMPLE_MATH),
- ("07v-interruptible-neuphonic-http.py", EVAL_SIMPLE_MATH),
- ("07w-interruptible-fal.py", EVAL_SIMPLE_MATH),
- ("07y-interruptible-minimax.py", EVAL_SIMPLE_MATH),
- ("07z-interruptible-sarvam.py", EVAL_SIMPLE_MATH),
- ("07z-interruptible-sarvam-http.py", EVAL_SIMPLE_MATH),
- ("07za-interruptible-soniox.py", EVAL_SIMPLE_MATH),
- ("07zb-interruptible-inworld.py", EVAL_SIMPLE_MATH),
- ("07zb-interruptible-inworld-http.py", EVAL_SIMPLE_MATH),
- ("07zc-interruptible-asyncai.py", EVAL_SIMPLE_MATH),
- ("07zc-interruptible-asyncai-http.py", EVAL_SIMPLE_MATH),
- ("07zd-interruptible-aicoustics.py", EVAL_SIMPLE_MATH),
- ("07ze-interruptible-hume.py", EVAL_SIMPLE_MATH),
- ("07zf-interruptible-gradium.py", EVAL_SIMPLE_MATH),
- ("07zg-interruptible-camb.py", EVAL_SIMPLE_MATH),
- ("07zi-interruptible-piper.py", EVAL_SIMPLE_MATH),
- ("07zj-interruptible-kokoro.py", EVAL_SIMPLE_MATH),
- ("07zk-interruptible-resembleai.py", EVAL_SIMPLE_MATH),
- ("07zl-interruptible-smallest.py", EVAL_SIMPLE_MATH),
- ("07-interruptible-openai-responses.py", EVAL_SIMPLE_MATH),
- ("07-interruptible-openai-responses-http.py", EVAL_SIMPLE_MATH),
+TESTS_SPEECH = [
+ ("services/speech/cartesia.py", EVAL_SIMPLE_MATH),
+ ("services/speech/cartesia-http.py", EVAL_SIMPLE_MATH),
+ ("services/speech/speechmatics.py", EVAL_SIMPLE_MATH),
+ ("services/speech/speechmatics-vad.py", EVAL_SIMPLE_MATH),
+ ("services/speech/langchain.py", EVAL_SIMPLE_MATH),
+ ("services/speech/deepgram.py", EVAL_SIMPLE_MATH),
+ ("services/speech/deepgram-flux.py", EVAL_SIMPLE_MATH),
+ ("services/speech/deepgram-http.py", EVAL_SIMPLE_MATH),
+ ("services/speech/elevenlabs.py", EVAL_SIMPLE_MATH),
+ ("services/speech/elevenlabs-http.py", EVAL_SIMPLE_MATH),
+ ("services/speech/xai.py", EVAL_SIMPLE_MATH),
+ ("services/speech/azure.py", EVAL_SIMPLE_MATH),
+ ("services/speech/azure-http.py", EVAL_SIMPLE_MATH),
+ ("services/speech/openai.py", EVAL_SIMPLE_MATH),
+ ("services/speech/openai-http.py", EVAL_SIMPLE_MATH),
+ ("services/speech/gladia.py", EVAL_SIMPLE_MATH),
+ ("services/speech/gladia-vad.py", EVAL_SIMPLE_MATH),
+ ("services/speech/lmnt.py", EVAL_SIMPLE_MATH),
+ ("services/speech/groq.py", EVAL_SIMPLE_MATH),
+ ("services/speech/aws.py", EVAL_SIMPLE_MATH),
+ ("services/speech/aws-strands.py", EVAL_WEATHER),
+ ("services/speech/google-gemini-tts.py", EVAL_SIMPLE_MATH),
+ ("services/speech/google.py", EVAL_SIMPLE_MATH),
+ ("services/speech/google-http.py", EVAL_SIMPLE_MATH),
+ ("services/speech/assemblyai.py", EVAL_SIMPLE_MATH),
+ ("services/speech/krisp-viva.py", EVAL_SIMPLE_MATH),
+ ("services/speech/rime.py", EVAL_SIMPLE_MATH),
+ ("services/speech/rime-http.py", EVAL_SIMPLE_MATH),
+ ("services/speech/nvidia.py", EVAL_SIMPLE_MATH),
+ ("services/speech/google-audio-in.py", EVAL_SIMPLE_MATH),
+ ("services/speech/fish.py", EVAL_SIMPLE_MATH),
+ ("services/speech/neuphonic.py", EVAL_SIMPLE_MATH),
+ ("services/speech/neuphonic-http.py", EVAL_SIMPLE_MATH),
+ ("services/speech/fal.py", EVAL_SIMPLE_MATH),
+ ("services/speech/minimax.py", EVAL_SIMPLE_MATH),
+ ("services/speech/sarvam.py", EVAL_SIMPLE_MATH),
+ ("services/speech/sarvam-http.py", EVAL_SIMPLE_MATH),
+ ("services/speech/soniox.py", EVAL_SIMPLE_MATH),
+ ("services/speech/inworld.py", EVAL_SIMPLE_MATH),
+ ("services/speech/inworld-http.py", EVAL_SIMPLE_MATH),
+ ("services/speech/asyncai.py", EVAL_SIMPLE_MATH),
+ ("services/speech/asyncai-http.py", EVAL_SIMPLE_MATH),
+ ("services/speech/aicoustics.py", EVAL_SIMPLE_MATH),
+ ("services/speech/hume.py", EVAL_SIMPLE_MATH),
+ ("services/speech/gradium.py", EVAL_SIMPLE_MATH),
+ ("services/speech/camb.py", EVAL_SIMPLE_MATH),
+ ("services/speech/piper.py", EVAL_SIMPLE_MATH),
+ ("services/speech/kokoro.py", EVAL_SIMPLE_MATH),
+ ("services/speech/resemble.py", EVAL_SIMPLE_MATH),
+ ("services/speech/smallest.py", EVAL_SIMPLE_MATH),
+ ("services/speech/openai-responses.py", EVAL_SIMPLE_MATH),
+ ("services/speech/openai-responses-http.py", EVAL_SIMPLE_MATH),
# Needs a local XTTS docker instance running.
- # ("07i-interruptible-xtts.py", EVAL_SIMPLE_MATH),
+ # ("services/speech/xtts.py", EVAL_SIMPLE_MATH),
]
-TESTS_12 = [
- ("12-describe-image-openai.py", EVAL_VISION_IMAGE(eval_speaks_first=True)),
- ("12-describe-image-openai-responses.py", EVAL_VISION_IMAGE(eval_speaks_first=True)),
- ("12-describe-image-openai-responses-http.py", EVAL_VISION_IMAGE(eval_speaks_first=True)),
- ("12a-describe-image-anthropic.py", EVAL_VISION_IMAGE(eval_speaks_first=True)),
- ("12b-describe-image-aws.py", EVAL_VISION_IMAGE(eval_speaks_first=True)),
- ("12c-describe-image-gemini-flash.py", EVAL_VISION_IMAGE(eval_speaks_first=True)),
- ("12d-describe-image-moondream.py", EVAL_VISION_IMAGE()),
+TESTS_VISION = [
+ ("vision/openai.py", EVAL_VISION_IMAGE(eval_speaks_first=True)),
+ ("vision/openai-responses.py", EVAL_VISION_IMAGE(eval_speaks_first=True)),
+ ("vision/openai-responses-http.py", EVAL_VISION_IMAGE(eval_speaks_first=True)),
+ ("vision/anthropic.py", EVAL_VISION_IMAGE(eval_speaks_first=True)),
+ ("vision/aws.py", EVAL_VISION_IMAGE(eval_speaks_first=True)),
+ ("vision/gemini-flash.py", EVAL_VISION_IMAGE(eval_speaks_first=True)),
+ ("vision/moondream.py", EVAL_VISION_IMAGE()),
]
# For a few major services, we also test parallel function calling.
# (We don't bother doing this with every single service, as it's expensive and
# most rely on the same OpenAI-compatible implementation.)
-TESTS_14 = [
- ("14-function-calling.py", EVAL_WEATHER),
- ("14-function-calling.py", EVAL_WEATHER_AND_RESTAURANT),
- ("14-function-calling-openai-responses.py", EVAL_WEATHER),
- ("14-function-calling-openai-responses.py", EVAL_WEATHER_AND_RESTAURANT),
- ("14-function-calling-openai-responses-http.py", EVAL_WEATHER),
- ("14-function-calling-openai-responses-http.py", EVAL_WEATHER_AND_RESTAURANT),
- ("14a-function-calling-anthropic.py", EVAL_WEATHER),
- ("14a-function-calling-anthropic.py", EVAL_WEATHER_AND_RESTAURANT),
- ("14b-function-calling-openai.py", EVAL_WEATHER),
- ("14e-function-calling-google.py", EVAL_WEATHER),
- ("14e-function-calling-google.py", EVAL_WEATHER_AND_RESTAURANT),
- ("14f-function-calling-groq.py", EVAL_WEATHER),
- ("14g-function-calling-grok.py", EVAL_WEATHER),
- ("14h-function-calling-azure.py", EVAL_WEATHER),
- ("14i-function-calling-fireworks.py", EVAL_WEATHER),
- ("14j-function-calling-nvidia.py", EVAL_WEATHER),
- ("14k-function-calling-cerebras.py", EVAL_WEATHER),
- ("14m-function-calling-openrouter.py", EVAL_WEATHER),
- ("14n-function-calling-perplexity.py", EVAL_WEATHER),
- ("14p-function-calling-gemini-vertex-ai.py", EVAL_WEATHER),
- ("14q-function-calling-qwen.py", EVAL_WEATHER),
- ("14r-function-calling-aws.py", EVAL_WEATHER),
- ("14s-function-calling-sambanova.py", EVAL_WEATHER),
- ("14r-function-calling-aws.py", EVAL_WEATHER_AND_RESTAURANT),
- ("14v-function-calling-nebius.py", EVAL_WEATHER),
- ("14w-function-calling-mistral.py", EVAL_WEATHER),
- ("14y-function-calling-sarvam.py", EVAL_WEATHER),
- ("14z-function-calling-novita.py", EVAL_WEATHER),
+TESTS_FUNCTION_CALLING = [
+ ("getting-started/07-function-calling.py", EVAL_WEATHER),
+ ("getting-started/07-function-calling.py", EVAL_WEATHER_AND_RESTAURANT),
+ ("services/function-calling/openai-responses.py", EVAL_WEATHER),
+ ("services/function-calling/openai-responses.py", EVAL_WEATHER_AND_RESTAURANT),
+ ("services/function-calling/openai-responses-http.py", EVAL_WEATHER),
+ ("services/function-calling/openai-responses-http.py", EVAL_WEATHER_AND_RESTAURANT),
+ ("services/function-calling/anthropic.py", EVAL_WEATHER),
+ ("services/function-calling/anthropic.py", EVAL_WEATHER_AND_RESTAURANT),
+ ("services/function-calling/openai.py", EVAL_WEATHER),
+ ("services/function-calling/google.py", EVAL_WEATHER),
+ ("services/function-calling/google.py", EVAL_WEATHER_AND_RESTAURANT),
+ ("services/function-calling/groq.py", EVAL_WEATHER),
+ ("services/function-calling/grok.py", EVAL_WEATHER),
+ ("services/function-calling/azure.py", EVAL_WEATHER),
+ ("services/function-calling/fireworks.py", EVAL_WEATHER),
+ ("services/function-calling/nvidia.py", EVAL_WEATHER),
+ ("services/function-calling/cerebras.py", EVAL_WEATHER),
+ ("services/function-calling/openrouter.py", EVAL_WEATHER),
+ ("services/function-calling/perplexity.py", EVAL_WEATHER),
+ ("services/function-calling/google-vertex.py", EVAL_WEATHER),
+ ("services/function-calling/qwen.py", EVAL_WEATHER),
+ ("services/function-calling/aws.py", EVAL_WEATHER),
+ ("services/function-calling/sambanova.py", EVAL_WEATHER),
+ ("services/function-calling/aws.py", EVAL_WEATHER_AND_RESTAURANT),
+ ("services/function-calling/nebius.py", EVAL_WEATHER),
+ ("services/function-calling/mistral.py", EVAL_WEATHER),
+ ("services/function-calling/sarvam.py", EVAL_WEATHER),
+ ("services/function-calling/novita.py", EVAL_WEATHER),
# Video
- ("14d-function-calling-anthropic-video.py", EVAL_VISION_CAMERA),
- ("14d-function-calling-aws-video.py", EVAL_VISION_CAMERA),
- ("14d-function-calling-gemini-flash-video.py", EVAL_VISION_CAMERA),
- ("14d-function-calling-moondream-video.py", EVAL_VISION_CAMERA),
- ("14d-function-calling-openai-video.py", EVAL_VISION_CAMERA),
- ("14d-function-calling-openai-responses-video.py", EVAL_VISION_CAMERA),
- ("14d-function-calling-openai-responses-video-http.py", EVAL_VISION_CAMERA),
+ ("services/function-calling/anthropic-video.py", EVAL_VISION_CAMERA),
+ ("services/function-calling/aws-video.py", EVAL_VISION_CAMERA),
+ ("services/function-calling/google-video.py", EVAL_VISION_CAMERA),
+ ("services/function-calling/moondream-video.py", EVAL_VISION_CAMERA),
+ ("services/function-calling/openai-video.py", EVAL_VISION_CAMERA),
+ ("services/function-calling/openai-responses-video.py", EVAL_VISION_CAMERA),
+ ("services/function-calling/openai-responses-video-http.py", EVAL_VISION_CAMERA),
# Currently not working.
- # ("14c-function-calling-together.py", EVAL_WEATHER),
- # ("14l-function-calling-deepseek.py", EVAL_WEATHER),
- # ("14o-function-calling-gemini-openai-format.py", EVAL_WEATHER),
+ # ("services/function-calling/together.py", EVAL_WEATHER),
+ # ("services/function-calling/deepseek.py", EVAL_WEATHER),
+ # ("services/function-calling/gemini-openai-format.py", EVAL_WEATHER),
]
-TESTS_15 = [
- ("15a-switch-languages.py", EVAL_SWITCH_LANGUAGE),
+TESTS_FEATURES = [
+ ("features/switch-languages.py", EVAL_SWITCH_LANGUAGE),
+ ("features/voicemail-detection.py", EVAL_VOICEMAIL),
+ ("features/voicemail-detection.py", EVAL_CONVERSATION),
+ ("features/concurrent-llm-evaluation.py", EVAL_SIMPLE_MATH),
]
-TESTS_19 = [
- ("19-openai-realtime.py", EVAL_WEATHER),
- ("19-openai-realtime-beta.py", EVAL_WEATHER),
+TESTS_REALTIME = [
+ ("realtime/openai.py", EVAL_WEATHER),
+ ("realtime/openai-beta.py", EVAL_WEATHER),
# OpenAI Realtime not released on Azure yet
- # ("19a-azure-realtime.py", EVAL_WEATHER),
- ("19a-azure-realtime-beta.py", EVAL_WEATHER),
- ("19b-openai-realtime-text.py", EVAL_WEATHER),
- ("19b-openai-realtime-beta-text.py", EVAL_WEATHER),
- ("19c-openai-realtime-live-video.py", EVAL_VISION_CAMERA),
-]
-
-TESTS_21 = [
- ("21a-tavus-video-service.py", EVAL_SIMPLE_MATH),
-]
-
-TESTS_22 = [
- ("22-filter-incomplete-turns.py", EVAL_COMPLETE_TURN),
-]
-
-TESTS_26 = [
- ("26-gemini-live.py", EVAL_SIMPLE_MATH),
- ("26a-gemini-live-local-vad.py", EVAL_SIMPLE_MATH),
- ("26b-gemini-live-function-calling.py", EVAL_WEATHER),
- ("26c-gemini-live-video.py", EVAL_VISION_CAMERA),
- ("26e-gemini-live-google-search.py", EVAL_ONLINE_SEARCH),
- ("26h-gemini-live-vertex-function-calling.py", EVAL_WEATHER),
+ # ("realtime/azure.py", EVAL_WEATHER),
+ ("realtime/azure-beta.py", EVAL_WEATHER),
+ ("realtime/openai-text.py", EVAL_WEATHER),
+ ("realtime/openai-beta-text.py", EVAL_WEATHER),
+ ("realtime/openai-live-video.py", EVAL_VISION_CAMERA),
+ ("realtime/gemini-live.py", EVAL_SIMPLE_MATH),
+ ("realtime/gemini-live-local-vad.py", EVAL_SIMPLE_MATH),
+ ("realtime/gemini-live-function-calling.py", EVAL_WEATHER),
+ ("realtime/gemini-live-video.py", EVAL_VISION_CAMERA),
+ ("realtime/gemini-live-google-search.py", EVAL_ONLINE_SEARCH),
+ ("realtime/gemini-live-vertex-function-calling.py", EVAL_WEATHER),
# Currently not working.
- # ("26d-gemini-live-text.py", EVAL_SIMPLE_MATH),
+ # ("realtime/gemini-live-text.py", EVAL_SIMPLE_MATH),
+ ("realtime/aws-nova-sonic.py", EVAL_SIMPLE_MATH),
+ ("realtime/ultravox.py", EVAL_ORDER),
+ ("realtime/grok.py", EVAL_WEATHER),
]
-TESTS_27 = [
- ("27-simli-layer.py", EVAL_SIMPLE_MATH),
+TESTS_VIDEO_AVATAR = [
+ ("video-avatar/tavus-video-service.py", EVAL_SIMPLE_MATH),
+ ("video-avatar/heygen-video-service.py", EVAL_SIMPLE_MATH),
+ ("video-avatar/simli-layer.py", EVAL_SIMPLE_MATH),
+ ("video-avatar/lemonslice-transport.py", EVAL_SIMPLE_MATH),
]
-TESTS_40 = [
- ("40-aws-nova-sonic.py", EVAL_SIMPLE_MATH),
+TESTS_TURN_MANAGEMENT = [
+ ("turn-management/filter-incomplete-turns.py", EVAL_COMPLETE_TURN),
]
-TESTS_43 = [
- ("43a-heygen-video-service.py", EVAL_SIMPLE_MATH),
-]
-
-TESTS_44 = [
- ("44-voicemail-detection.py", EVAL_VOICEMAIL),
- ("44-voicemail-detection.py", EVAL_CONVERSATION),
-]
-
-TESTS_49 = [
- ("49a-thinking-anthropic.py", EVAL_SIMPLE_MATH),
- ("49b-thinking-google.py", EVAL_SIMPLE_MATH),
- ("49c-thinking-functions-anthropic.py", EVAL_FLIGHT_STATUS),
- ("49d-thinking-functions-google.py", EVAL_FLIGHT_STATUS),
-]
-
-
-TESTS_50 = [
- ("50-ultravox-realtime.py", EVAL_ORDER),
-]
-
-
-TESTS_51 = [
- ("51-grok-realtime.py", EVAL_WEATHER),
-]
-
-TESTS_53 = [
- ("53-concurrent-llm-evaluation.py", EVAL_SIMPLE_MATH),
-]
-
-TESTS_56 = [
- ("56-lemonslice-transport.py", EVAL_SIMPLE_MATH),
+TESTS_THINKING_AND_MCP = [
+ ("thinking-and-mcp/thinking-anthropic.py", EVAL_SIMPLE_MATH),
+ ("thinking-and-mcp/thinking-google.py", EVAL_SIMPLE_MATH),
+ ("thinking-and-mcp/thinking-functions-anthropic.py", EVAL_FLIGHT_STATUS),
+ ("thinking-and-mcp/thinking-functions-google.py", EVAL_FLIGHT_STATUS),
]
TESTS = [
- *TESTS_07,
- *TESTS_12,
- *TESTS_14,
- *TESTS_15,
- *TESTS_19,
- *TESTS_21,
- *TESTS_22,
- *TESTS_26,
- *TESTS_27,
- *TESTS_40,
- *TESTS_43,
- *TESTS_44,
- *TESTS_49,
- *TESTS_50,
- *TESTS_51,
- *TESTS_53,
- *TESTS_56,
+ *TESTS_SPEECH,
+ *TESTS_VISION,
+ *TESTS_FUNCTION_CALLING,
+ *TESTS_FEATURES,
+ *TESTS_REALTIME,
+ *TESTS_VIDEO_AVATAR,
+ *TESTS_TURN_MANAGEMENT,
+ *TESTS_THINKING_AND_MCP,
]
From 1d85aedcaecd1b1043f8efc07ba60eb0e49ebdae Mon Sep 17 00:00:00 2001
From: Mark Backman
Date: Tue, 31 Mar 2026 13:15:06 -0400
Subject: [PATCH 09/19] Split features/ into audio/, observability/, and rag/
subfolders
Extract focused example groups from the catch-all features/ folder:
- audio/: audio recording, background sound, sound effects
- observability/: observer, heartbeats, sentry metrics
- rag/: mem0, gemini-rag, gemini grounding metadata
Update README to document the new folders.
---
examples/README.md | 14 +++++++++++++-
examples/{features => audio}/audio-recording.py | 0
.../{features => audio}/bot-background-sound.py | 0
examples/{features => audio}/sound-effects.py | 0
examples/{features => observability}/heartbeats.py | 0
examples/{features => observability}/observer.py | 0
.../{features => observability}/sentry-metrics.py | 0
.../{features => rag}/gemini-grounding-metadata.py | 0
examples/{features => rag}/gemini-rag.py | 0
examples/{features => rag}/mem0.py | 0
10 files changed, 13 insertions(+), 1 deletion(-)
rename examples/{features => audio}/audio-recording.py (100%)
rename examples/{features => audio}/bot-background-sound.py (100%)
rename examples/{features => audio}/sound-effects.py (100%)
rename examples/{features => observability}/heartbeats.py (100%)
rename examples/{features => observability}/observer.py (100%)
rename examples/{features => observability}/sentry-metrics.py (100%)
rename examples/{features => rag}/gemini-grounding-metadata.py (100%)
rename examples/{features => rag}/gemini-rag.py (100%)
rename examples/{features => rag}/mem0.py (100%)
diff --git a/examples/README.md b/examples/README.md
index f584d3768..08dc58de5 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -116,9 +116,21 @@ Video avatar integrations (Tavus, HeyGen, Simli, LemonSlice).
Video processing, mirroring, GStreamer, and custom video tracks.
+### [`audio/`](./audio/)
+
+Audio recording, background sounds, and sound effects.
+
+### [`observability/`](./observability/)
+
+Pipeline monitoring: observers, heartbeats, and Sentry metrics.
+
+### [`rag/`](./rag/)
+
+Retrieval-augmented generation, grounding, and long-term memory (Mem0, Gemini).
+
### [`features/`](./features/)
-Miscellaneous features: sound effects, wake phrases, observers, audio recording, live translation, service switching, and more.
+Miscellaneous features: wake phrases, live translation, service switching, voice switching, and more.
## Advanced Usage
diff --git a/examples/features/audio-recording.py b/examples/audio/audio-recording.py
similarity index 100%
rename from examples/features/audio-recording.py
rename to examples/audio/audio-recording.py
diff --git a/examples/features/bot-background-sound.py b/examples/audio/bot-background-sound.py
similarity index 100%
rename from examples/features/bot-background-sound.py
rename to examples/audio/bot-background-sound.py
diff --git a/examples/features/sound-effects.py b/examples/audio/sound-effects.py
similarity index 100%
rename from examples/features/sound-effects.py
rename to examples/audio/sound-effects.py
diff --git a/examples/features/heartbeats.py b/examples/observability/heartbeats.py
similarity index 100%
rename from examples/features/heartbeats.py
rename to examples/observability/heartbeats.py
diff --git a/examples/features/observer.py b/examples/observability/observer.py
similarity index 100%
rename from examples/features/observer.py
rename to examples/observability/observer.py
diff --git a/examples/features/sentry-metrics.py b/examples/observability/sentry-metrics.py
similarity index 100%
rename from examples/features/sentry-metrics.py
rename to examples/observability/sentry-metrics.py
diff --git a/examples/features/gemini-grounding-metadata.py b/examples/rag/gemini-grounding-metadata.py
similarity index 100%
rename from examples/features/gemini-grounding-metadata.py
rename to examples/rag/gemini-grounding-metadata.py
diff --git a/examples/features/gemini-rag.py b/examples/rag/gemini-rag.py
similarity index 100%
rename from examples/features/gemini-rag.py
rename to examples/rag/gemini-rag.py
diff --git a/examples/features/mem0.py b/examples/rag/mem0.py
similarity index 100%
rename from examples/features/mem0.py
rename to examples/rag/mem0.py
From e1939ecd4447bbe1cd1a81f3c72f9810420db5de Mon Sep 17 00:00:00 2001
From: Mark Backman
Date: Tue, 31 Mar 2026 14:55:22 -0400
Subject: [PATCH 10/19] Flatten services/ nesting: promote speech and
function-calling to top level
Move services/speech/* directly into services/ and services/function-calling/*
into top-level function-calling/. Update eval script paths and README.
---
examples/README.md | 7 +-
.../function-calling/anthropic-video.py | 0
.../function-calling/anthropic.py | 0
.../function-calling/aws-video.py | 0
.../{services => }/function-calling/aws.py | 0
.../{services => }/function-calling/azure.py | 0
.../function-calling/cerebras.py | 0
.../function-calling/deepseek.py | 0
.../{services => }/function-calling/direct.py | 0
.../function-calling/fireworks.py | 0
.../function-calling/gemini-openai-format.py | 0
.../function-calling/google-vertex-ai.py | 0
.../function-calling/google-video.py | 0
.../{services => }/function-calling/google.py | 0
.../{services => }/function-calling/grok.py | 0
.../{services => }/function-calling/groq.py | 0
.../function-calling/mistral.py | 0
.../function-calling/moondream-video.py | 0
.../{services => }/function-calling/nebius.py | 0
.../{services => }/function-calling/novita.py | 0
.../{services => }/function-calling/nvidia.py | 0
.../{services => }/function-calling/ollama.py | 0
.../function-calling/openai-responses-http.py | 0
.../openai-responses-video-http.py | 0
.../openai-responses-video.py | 0
.../function-calling/openai-responses.py | 0
.../function-calling/openai-video.py | 0
.../{services => }/function-calling/openai.py | 0
.../function-calling/openrouter.py | 0
.../function-calling/perplexity.py | 0
.../{services => }/function-calling/qwen.py | 0
.../function-calling/sambanova.py | 0
.../{services => }/function-calling/sarvam.py | 0
.../function-calling/together.py | 0
examples/services/{speech => }/aicoustics.py | 0
.../{speech => }/assemblyai-turn-detection.py | 0
examples/services/{speech => }/assemblyai.py | 0
.../services/{speech => }/asyncai-http.py | 0
examples/services/{speech => }/asyncai.py | 0
examples/services/{speech => }/aws-strands.py | 0
examples/services/{speech => }/aws.py | 0
examples/services/{speech => }/azure-http.py | 0
examples/services/{speech => }/azure.py | 0
examples/services/{speech => }/camb.py | 0
.../services/{speech => }/cartesia-http.py | 0
examples/services/{speech => }/cartesia.py | 0
.../{speech => }/deepgram-flux-sagemaker.py | 0
.../services/{speech => }/deepgram-flux.py | 0
.../services/{speech => }/deepgram-http.py | 0
.../{speech => }/deepgram-sagemaker.py | 0
.../services/{speech => }/deepgram-vad.py | 0
examples/services/{speech => }/deepgram.py | 0
.../services/{speech => }/elevenlabs-http.py | 0
examples/services/{speech => }/elevenlabs.py | 0
examples/services/{speech => }/fal.py | 0
examples/services/{speech => }/fish.py | 0
examples/services/{speech => }/gladia-vad.py | 0
examples/services/{speech => }/gladia.py | 0
.../services/{speech => }/google-audio-in.py | 0
.../{speech => }/google-gemini-tts.py | 0
examples/services/{speech => }/google-http.py | 0
.../services/{speech => }/google-image.py | 0
examples/services/{speech => }/google.py | 0
examples/services/{speech => }/gradium.py | 0
examples/services/{speech => }/groq.py | 0
examples/services/{speech => }/hume.py | 0
.../services/{speech => }/inworld-http.py | 0
examples/services/{speech => }/inworld.py | 0
examples/services/{speech => }/kokoro.py | 0
examples/services/{speech => }/krisp-viva.py | 0
examples/services/{speech => }/langchain.py | 0
examples/services/{speech => }/lmnt.py | 0
examples/services/{speech => }/minimax.py | 0
.../services/{speech => }/neuphonic-http.py | 0
examples/services/{speech => }/neuphonic.py | 0
examples/services/{speech => }/nvidia.py | 0
examples/services/{speech => }/openai-http.py | 0
.../{speech => }/openai-responses-http.py | 0
.../services/{speech => }/openai-responses.py | 0
examples/services/{speech => }/openai.py | 0
examples/services/{speech => }/piper.py | 0
examples/services/{speech => }/resemble.py | 0
examples/services/{speech => }/rime-http.py | 0
examples/services/{speech => }/rime.py | 0
examples/services/{speech => }/sarvam-http.py | 0
examples/services/{speech => }/sarvam.py | 0
examples/services/{speech => }/smallest.py | 0
examples/services/{speech => }/soniox.py | 0
.../services/{speech => }/speechmatics-vad.py | 0
.../services/{speech => }/speechmatics.py | 0
examples/services/{speech => }/xai.py | 0
examples/services/{speech => }/xtts.py | 0
scripts/evals/run-release-evals.py | 178 +++++++++---------
93 files changed, 93 insertions(+), 92 deletions(-)
rename examples/{services => }/function-calling/anthropic-video.py (100%)
rename examples/{services => }/function-calling/anthropic.py (100%)
rename examples/{services => }/function-calling/aws-video.py (100%)
rename examples/{services => }/function-calling/aws.py (100%)
rename examples/{services => }/function-calling/azure.py (100%)
rename examples/{services => }/function-calling/cerebras.py (100%)
rename examples/{services => }/function-calling/deepseek.py (100%)
rename examples/{services => }/function-calling/direct.py (100%)
rename examples/{services => }/function-calling/fireworks.py (100%)
rename examples/{services => }/function-calling/gemini-openai-format.py (100%)
rename examples/{services => }/function-calling/google-vertex-ai.py (100%)
rename examples/{services => }/function-calling/google-video.py (100%)
rename examples/{services => }/function-calling/google.py (100%)
rename examples/{services => }/function-calling/grok.py (100%)
rename examples/{services => }/function-calling/groq.py (100%)
rename examples/{services => }/function-calling/mistral.py (100%)
rename examples/{services => }/function-calling/moondream-video.py (100%)
rename examples/{services => }/function-calling/nebius.py (100%)
rename examples/{services => }/function-calling/novita.py (100%)
rename examples/{services => }/function-calling/nvidia.py (100%)
rename examples/{services => }/function-calling/ollama.py (100%)
rename examples/{services => }/function-calling/openai-responses-http.py (100%)
rename examples/{services => }/function-calling/openai-responses-video-http.py (100%)
rename examples/{services => }/function-calling/openai-responses-video.py (100%)
rename examples/{services => }/function-calling/openai-responses.py (100%)
rename examples/{services => }/function-calling/openai-video.py (100%)
rename examples/{services => }/function-calling/openai.py (100%)
rename examples/{services => }/function-calling/openrouter.py (100%)
rename examples/{services => }/function-calling/perplexity.py (100%)
rename examples/{services => }/function-calling/qwen.py (100%)
rename examples/{services => }/function-calling/sambanova.py (100%)
rename examples/{services => }/function-calling/sarvam.py (100%)
rename examples/{services => }/function-calling/together.py (100%)
rename examples/services/{speech => }/aicoustics.py (100%)
rename examples/services/{speech => }/assemblyai-turn-detection.py (100%)
rename examples/services/{speech => }/assemblyai.py (100%)
rename examples/services/{speech => }/asyncai-http.py (100%)
rename examples/services/{speech => }/asyncai.py (100%)
rename examples/services/{speech => }/aws-strands.py (100%)
rename examples/services/{speech => }/aws.py (100%)
rename examples/services/{speech => }/azure-http.py (100%)
rename examples/services/{speech => }/azure.py (100%)
rename examples/services/{speech => }/camb.py (100%)
rename examples/services/{speech => }/cartesia-http.py (100%)
rename examples/services/{speech => }/cartesia.py (100%)
rename examples/services/{speech => }/deepgram-flux-sagemaker.py (100%)
rename examples/services/{speech => }/deepgram-flux.py (100%)
rename examples/services/{speech => }/deepgram-http.py (100%)
rename examples/services/{speech => }/deepgram-sagemaker.py (100%)
rename examples/services/{speech => }/deepgram-vad.py (100%)
rename examples/services/{speech => }/deepgram.py (100%)
rename examples/services/{speech => }/elevenlabs-http.py (100%)
rename examples/services/{speech => }/elevenlabs.py (100%)
rename examples/services/{speech => }/fal.py (100%)
rename examples/services/{speech => }/fish.py (100%)
rename examples/services/{speech => }/gladia-vad.py (100%)
rename examples/services/{speech => }/gladia.py (100%)
rename examples/services/{speech => }/google-audio-in.py (100%)
rename examples/services/{speech => }/google-gemini-tts.py (100%)
rename examples/services/{speech => }/google-http.py (100%)
rename examples/services/{speech => }/google-image.py (100%)
rename examples/services/{speech => }/google.py (100%)
rename examples/services/{speech => }/gradium.py (100%)
rename examples/services/{speech => }/groq.py (100%)
rename examples/services/{speech => }/hume.py (100%)
rename examples/services/{speech => }/inworld-http.py (100%)
rename examples/services/{speech => }/inworld.py (100%)
rename examples/services/{speech => }/kokoro.py (100%)
rename examples/services/{speech => }/krisp-viva.py (100%)
rename examples/services/{speech => }/langchain.py (100%)
rename examples/services/{speech => }/lmnt.py (100%)
rename examples/services/{speech => }/minimax.py (100%)
rename examples/services/{speech => }/neuphonic-http.py (100%)
rename examples/services/{speech => }/neuphonic.py (100%)
rename examples/services/{speech => }/nvidia.py (100%)
rename examples/services/{speech => }/openai-http.py (100%)
rename examples/services/{speech => }/openai-responses-http.py (100%)
rename examples/services/{speech => }/openai-responses.py (100%)
rename examples/services/{speech => }/openai.py (100%)
rename examples/services/{speech => }/piper.py (100%)
rename examples/services/{speech => }/resemble.py (100%)
rename examples/services/{speech => }/rime-http.py (100%)
rename examples/services/{speech => }/rime.py (100%)
rename examples/services/{speech => }/sarvam-http.py (100%)
rename examples/services/{speech => }/sarvam.py (100%)
rename examples/services/{speech => }/smallest.py (100%)
rename examples/services/{speech => }/soniox.py (100%)
rename examples/services/{speech => }/speechmatics-vad.py (100%)
rename examples/services/{speech => }/speechmatics.py (100%)
rename examples/services/{speech => }/xai.py (100%)
rename examples/services/{speech => }/xtts.py (100%)
diff --git a/examples/README.md b/examples/README.md
index 08dc58de5..a7fabaa73 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -63,10 +63,11 @@ Progressive introduction to Pipecat, from minimal TTS to a full voice agent with
### [`services/`](./services/)
-Service provider integration examples, organized into subfolders:
+Full STT + LLM + TTS pipelines showcasing different speech service providers (Deepgram, ElevenLabs, Cartesia, etc.)
-- **[`speech/`](./services/speech/)** — Full STT + LLM + TTS pipelines showcasing different speech service providers (Deepgram, ElevenLabs, Cartesia, etc.)
-- **[`function-calling/`](./services/function-calling/)** — Function calling with different LLM providers (OpenAI, Anthropic, Google, etc.)
+### [`function-calling/`](./function-calling/)
+
+Function calling with different LLM providers (OpenAI, Anthropic, Google, etc.)
### [`transcription/`](./transcription/)
diff --git a/examples/services/function-calling/anthropic-video.py b/examples/function-calling/anthropic-video.py
similarity index 100%
rename from examples/services/function-calling/anthropic-video.py
rename to examples/function-calling/anthropic-video.py
diff --git a/examples/services/function-calling/anthropic.py b/examples/function-calling/anthropic.py
similarity index 100%
rename from examples/services/function-calling/anthropic.py
rename to examples/function-calling/anthropic.py
diff --git a/examples/services/function-calling/aws-video.py b/examples/function-calling/aws-video.py
similarity index 100%
rename from examples/services/function-calling/aws-video.py
rename to examples/function-calling/aws-video.py
diff --git a/examples/services/function-calling/aws.py b/examples/function-calling/aws.py
similarity index 100%
rename from examples/services/function-calling/aws.py
rename to examples/function-calling/aws.py
diff --git a/examples/services/function-calling/azure.py b/examples/function-calling/azure.py
similarity index 100%
rename from examples/services/function-calling/azure.py
rename to examples/function-calling/azure.py
diff --git a/examples/services/function-calling/cerebras.py b/examples/function-calling/cerebras.py
similarity index 100%
rename from examples/services/function-calling/cerebras.py
rename to examples/function-calling/cerebras.py
diff --git a/examples/services/function-calling/deepseek.py b/examples/function-calling/deepseek.py
similarity index 100%
rename from examples/services/function-calling/deepseek.py
rename to examples/function-calling/deepseek.py
diff --git a/examples/services/function-calling/direct.py b/examples/function-calling/direct.py
similarity index 100%
rename from examples/services/function-calling/direct.py
rename to examples/function-calling/direct.py
diff --git a/examples/services/function-calling/fireworks.py b/examples/function-calling/fireworks.py
similarity index 100%
rename from examples/services/function-calling/fireworks.py
rename to examples/function-calling/fireworks.py
diff --git a/examples/services/function-calling/gemini-openai-format.py b/examples/function-calling/gemini-openai-format.py
similarity index 100%
rename from examples/services/function-calling/gemini-openai-format.py
rename to examples/function-calling/gemini-openai-format.py
diff --git a/examples/services/function-calling/google-vertex-ai.py b/examples/function-calling/google-vertex-ai.py
similarity index 100%
rename from examples/services/function-calling/google-vertex-ai.py
rename to examples/function-calling/google-vertex-ai.py
diff --git a/examples/services/function-calling/google-video.py b/examples/function-calling/google-video.py
similarity index 100%
rename from examples/services/function-calling/google-video.py
rename to examples/function-calling/google-video.py
diff --git a/examples/services/function-calling/google.py b/examples/function-calling/google.py
similarity index 100%
rename from examples/services/function-calling/google.py
rename to examples/function-calling/google.py
diff --git a/examples/services/function-calling/grok.py b/examples/function-calling/grok.py
similarity index 100%
rename from examples/services/function-calling/grok.py
rename to examples/function-calling/grok.py
diff --git a/examples/services/function-calling/groq.py b/examples/function-calling/groq.py
similarity index 100%
rename from examples/services/function-calling/groq.py
rename to examples/function-calling/groq.py
diff --git a/examples/services/function-calling/mistral.py b/examples/function-calling/mistral.py
similarity index 100%
rename from examples/services/function-calling/mistral.py
rename to examples/function-calling/mistral.py
diff --git a/examples/services/function-calling/moondream-video.py b/examples/function-calling/moondream-video.py
similarity index 100%
rename from examples/services/function-calling/moondream-video.py
rename to examples/function-calling/moondream-video.py
diff --git a/examples/services/function-calling/nebius.py b/examples/function-calling/nebius.py
similarity index 100%
rename from examples/services/function-calling/nebius.py
rename to examples/function-calling/nebius.py
diff --git a/examples/services/function-calling/novita.py b/examples/function-calling/novita.py
similarity index 100%
rename from examples/services/function-calling/novita.py
rename to examples/function-calling/novita.py
diff --git a/examples/services/function-calling/nvidia.py b/examples/function-calling/nvidia.py
similarity index 100%
rename from examples/services/function-calling/nvidia.py
rename to examples/function-calling/nvidia.py
diff --git a/examples/services/function-calling/ollama.py b/examples/function-calling/ollama.py
similarity index 100%
rename from examples/services/function-calling/ollama.py
rename to examples/function-calling/ollama.py
diff --git a/examples/services/function-calling/openai-responses-http.py b/examples/function-calling/openai-responses-http.py
similarity index 100%
rename from examples/services/function-calling/openai-responses-http.py
rename to examples/function-calling/openai-responses-http.py
diff --git a/examples/services/function-calling/openai-responses-video-http.py b/examples/function-calling/openai-responses-video-http.py
similarity index 100%
rename from examples/services/function-calling/openai-responses-video-http.py
rename to examples/function-calling/openai-responses-video-http.py
diff --git a/examples/services/function-calling/openai-responses-video.py b/examples/function-calling/openai-responses-video.py
similarity index 100%
rename from examples/services/function-calling/openai-responses-video.py
rename to examples/function-calling/openai-responses-video.py
diff --git a/examples/services/function-calling/openai-responses.py b/examples/function-calling/openai-responses.py
similarity index 100%
rename from examples/services/function-calling/openai-responses.py
rename to examples/function-calling/openai-responses.py
diff --git a/examples/services/function-calling/openai-video.py b/examples/function-calling/openai-video.py
similarity index 100%
rename from examples/services/function-calling/openai-video.py
rename to examples/function-calling/openai-video.py
diff --git a/examples/services/function-calling/openai.py b/examples/function-calling/openai.py
similarity index 100%
rename from examples/services/function-calling/openai.py
rename to examples/function-calling/openai.py
diff --git a/examples/services/function-calling/openrouter.py b/examples/function-calling/openrouter.py
similarity index 100%
rename from examples/services/function-calling/openrouter.py
rename to examples/function-calling/openrouter.py
diff --git a/examples/services/function-calling/perplexity.py b/examples/function-calling/perplexity.py
similarity index 100%
rename from examples/services/function-calling/perplexity.py
rename to examples/function-calling/perplexity.py
diff --git a/examples/services/function-calling/qwen.py b/examples/function-calling/qwen.py
similarity index 100%
rename from examples/services/function-calling/qwen.py
rename to examples/function-calling/qwen.py
diff --git a/examples/services/function-calling/sambanova.py b/examples/function-calling/sambanova.py
similarity index 100%
rename from examples/services/function-calling/sambanova.py
rename to examples/function-calling/sambanova.py
diff --git a/examples/services/function-calling/sarvam.py b/examples/function-calling/sarvam.py
similarity index 100%
rename from examples/services/function-calling/sarvam.py
rename to examples/function-calling/sarvam.py
diff --git a/examples/services/function-calling/together.py b/examples/function-calling/together.py
similarity index 100%
rename from examples/services/function-calling/together.py
rename to examples/function-calling/together.py
diff --git a/examples/services/speech/aicoustics.py b/examples/services/aicoustics.py
similarity index 100%
rename from examples/services/speech/aicoustics.py
rename to examples/services/aicoustics.py
diff --git a/examples/services/speech/assemblyai-turn-detection.py b/examples/services/assemblyai-turn-detection.py
similarity index 100%
rename from examples/services/speech/assemblyai-turn-detection.py
rename to examples/services/assemblyai-turn-detection.py
diff --git a/examples/services/speech/assemblyai.py b/examples/services/assemblyai.py
similarity index 100%
rename from examples/services/speech/assemblyai.py
rename to examples/services/assemblyai.py
diff --git a/examples/services/speech/asyncai-http.py b/examples/services/asyncai-http.py
similarity index 100%
rename from examples/services/speech/asyncai-http.py
rename to examples/services/asyncai-http.py
diff --git a/examples/services/speech/asyncai.py b/examples/services/asyncai.py
similarity index 100%
rename from examples/services/speech/asyncai.py
rename to examples/services/asyncai.py
diff --git a/examples/services/speech/aws-strands.py b/examples/services/aws-strands.py
similarity index 100%
rename from examples/services/speech/aws-strands.py
rename to examples/services/aws-strands.py
diff --git a/examples/services/speech/aws.py b/examples/services/aws.py
similarity index 100%
rename from examples/services/speech/aws.py
rename to examples/services/aws.py
diff --git a/examples/services/speech/azure-http.py b/examples/services/azure-http.py
similarity index 100%
rename from examples/services/speech/azure-http.py
rename to examples/services/azure-http.py
diff --git a/examples/services/speech/azure.py b/examples/services/azure.py
similarity index 100%
rename from examples/services/speech/azure.py
rename to examples/services/azure.py
diff --git a/examples/services/speech/camb.py b/examples/services/camb.py
similarity index 100%
rename from examples/services/speech/camb.py
rename to examples/services/camb.py
diff --git a/examples/services/speech/cartesia-http.py b/examples/services/cartesia-http.py
similarity index 100%
rename from examples/services/speech/cartesia-http.py
rename to examples/services/cartesia-http.py
diff --git a/examples/services/speech/cartesia.py b/examples/services/cartesia.py
similarity index 100%
rename from examples/services/speech/cartesia.py
rename to examples/services/cartesia.py
diff --git a/examples/services/speech/deepgram-flux-sagemaker.py b/examples/services/deepgram-flux-sagemaker.py
similarity index 100%
rename from examples/services/speech/deepgram-flux-sagemaker.py
rename to examples/services/deepgram-flux-sagemaker.py
diff --git a/examples/services/speech/deepgram-flux.py b/examples/services/deepgram-flux.py
similarity index 100%
rename from examples/services/speech/deepgram-flux.py
rename to examples/services/deepgram-flux.py
diff --git a/examples/services/speech/deepgram-http.py b/examples/services/deepgram-http.py
similarity index 100%
rename from examples/services/speech/deepgram-http.py
rename to examples/services/deepgram-http.py
diff --git a/examples/services/speech/deepgram-sagemaker.py b/examples/services/deepgram-sagemaker.py
similarity index 100%
rename from examples/services/speech/deepgram-sagemaker.py
rename to examples/services/deepgram-sagemaker.py
diff --git a/examples/services/speech/deepgram-vad.py b/examples/services/deepgram-vad.py
similarity index 100%
rename from examples/services/speech/deepgram-vad.py
rename to examples/services/deepgram-vad.py
diff --git a/examples/services/speech/deepgram.py b/examples/services/deepgram.py
similarity index 100%
rename from examples/services/speech/deepgram.py
rename to examples/services/deepgram.py
diff --git a/examples/services/speech/elevenlabs-http.py b/examples/services/elevenlabs-http.py
similarity index 100%
rename from examples/services/speech/elevenlabs-http.py
rename to examples/services/elevenlabs-http.py
diff --git a/examples/services/speech/elevenlabs.py b/examples/services/elevenlabs.py
similarity index 100%
rename from examples/services/speech/elevenlabs.py
rename to examples/services/elevenlabs.py
diff --git a/examples/services/speech/fal.py b/examples/services/fal.py
similarity index 100%
rename from examples/services/speech/fal.py
rename to examples/services/fal.py
diff --git a/examples/services/speech/fish.py b/examples/services/fish.py
similarity index 100%
rename from examples/services/speech/fish.py
rename to examples/services/fish.py
diff --git a/examples/services/speech/gladia-vad.py b/examples/services/gladia-vad.py
similarity index 100%
rename from examples/services/speech/gladia-vad.py
rename to examples/services/gladia-vad.py
diff --git a/examples/services/speech/gladia.py b/examples/services/gladia.py
similarity index 100%
rename from examples/services/speech/gladia.py
rename to examples/services/gladia.py
diff --git a/examples/services/speech/google-audio-in.py b/examples/services/google-audio-in.py
similarity index 100%
rename from examples/services/speech/google-audio-in.py
rename to examples/services/google-audio-in.py
diff --git a/examples/services/speech/google-gemini-tts.py b/examples/services/google-gemini-tts.py
similarity index 100%
rename from examples/services/speech/google-gemini-tts.py
rename to examples/services/google-gemini-tts.py
diff --git a/examples/services/speech/google-http.py b/examples/services/google-http.py
similarity index 100%
rename from examples/services/speech/google-http.py
rename to examples/services/google-http.py
diff --git a/examples/services/speech/google-image.py b/examples/services/google-image.py
similarity index 100%
rename from examples/services/speech/google-image.py
rename to examples/services/google-image.py
diff --git a/examples/services/speech/google.py b/examples/services/google.py
similarity index 100%
rename from examples/services/speech/google.py
rename to examples/services/google.py
diff --git a/examples/services/speech/gradium.py b/examples/services/gradium.py
similarity index 100%
rename from examples/services/speech/gradium.py
rename to examples/services/gradium.py
diff --git a/examples/services/speech/groq.py b/examples/services/groq.py
similarity index 100%
rename from examples/services/speech/groq.py
rename to examples/services/groq.py
diff --git a/examples/services/speech/hume.py b/examples/services/hume.py
similarity index 100%
rename from examples/services/speech/hume.py
rename to examples/services/hume.py
diff --git a/examples/services/speech/inworld-http.py b/examples/services/inworld-http.py
similarity index 100%
rename from examples/services/speech/inworld-http.py
rename to examples/services/inworld-http.py
diff --git a/examples/services/speech/inworld.py b/examples/services/inworld.py
similarity index 100%
rename from examples/services/speech/inworld.py
rename to examples/services/inworld.py
diff --git a/examples/services/speech/kokoro.py b/examples/services/kokoro.py
similarity index 100%
rename from examples/services/speech/kokoro.py
rename to examples/services/kokoro.py
diff --git a/examples/services/speech/krisp-viva.py b/examples/services/krisp-viva.py
similarity index 100%
rename from examples/services/speech/krisp-viva.py
rename to examples/services/krisp-viva.py
diff --git a/examples/services/speech/langchain.py b/examples/services/langchain.py
similarity index 100%
rename from examples/services/speech/langchain.py
rename to examples/services/langchain.py
diff --git a/examples/services/speech/lmnt.py b/examples/services/lmnt.py
similarity index 100%
rename from examples/services/speech/lmnt.py
rename to examples/services/lmnt.py
diff --git a/examples/services/speech/minimax.py b/examples/services/minimax.py
similarity index 100%
rename from examples/services/speech/minimax.py
rename to examples/services/minimax.py
diff --git a/examples/services/speech/neuphonic-http.py b/examples/services/neuphonic-http.py
similarity index 100%
rename from examples/services/speech/neuphonic-http.py
rename to examples/services/neuphonic-http.py
diff --git a/examples/services/speech/neuphonic.py b/examples/services/neuphonic.py
similarity index 100%
rename from examples/services/speech/neuphonic.py
rename to examples/services/neuphonic.py
diff --git a/examples/services/speech/nvidia.py b/examples/services/nvidia.py
similarity index 100%
rename from examples/services/speech/nvidia.py
rename to examples/services/nvidia.py
diff --git a/examples/services/speech/openai-http.py b/examples/services/openai-http.py
similarity index 100%
rename from examples/services/speech/openai-http.py
rename to examples/services/openai-http.py
diff --git a/examples/services/speech/openai-responses-http.py b/examples/services/openai-responses-http.py
similarity index 100%
rename from examples/services/speech/openai-responses-http.py
rename to examples/services/openai-responses-http.py
diff --git a/examples/services/speech/openai-responses.py b/examples/services/openai-responses.py
similarity index 100%
rename from examples/services/speech/openai-responses.py
rename to examples/services/openai-responses.py
diff --git a/examples/services/speech/openai.py b/examples/services/openai.py
similarity index 100%
rename from examples/services/speech/openai.py
rename to examples/services/openai.py
diff --git a/examples/services/speech/piper.py b/examples/services/piper.py
similarity index 100%
rename from examples/services/speech/piper.py
rename to examples/services/piper.py
diff --git a/examples/services/speech/resemble.py b/examples/services/resemble.py
similarity index 100%
rename from examples/services/speech/resemble.py
rename to examples/services/resemble.py
diff --git a/examples/services/speech/rime-http.py b/examples/services/rime-http.py
similarity index 100%
rename from examples/services/speech/rime-http.py
rename to examples/services/rime-http.py
diff --git a/examples/services/speech/rime.py b/examples/services/rime.py
similarity index 100%
rename from examples/services/speech/rime.py
rename to examples/services/rime.py
diff --git a/examples/services/speech/sarvam-http.py b/examples/services/sarvam-http.py
similarity index 100%
rename from examples/services/speech/sarvam-http.py
rename to examples/services/sarvam-http.py
diff --git a/examples/services/speech/sarvam.py b/examples/services/sarvam.py
similarity index 100%
rename from examples/services/speech/sarvam.py
rename to examples/services/sarvam.py
diff --git a/examples/services/speech/smallest.py b/examples/services/smallest.py
similarity index 100%
rename from examples/services/speech/smallest.py
rename to examples/services/smallest.py
diff --git a/examples/services/speech/soniox.py b/examples/services/soniox.py
similarity index 100%
rename from examples/services/speech/soniox.py
rename to examples/services/soniox.py
diff --git a/examples/services/speech/speechmatics-vad.py b/examples/services/speechmatics-vad.py
similarity index 100%
rename from examples/services/speech/speechmatics-vad.py
rename to examples/services/speechmatics-vad.py
diff --git a/examples/services/speech/speechmatics.py b/examples/services/speechmatics.py
similarity index 100%
rename from examples/services/speech/speechmatics.py
rename to examples/services/speechmatics.py
diff --git a/examples/services/speech/xai.py b/examples/services/xai.py
similarity index 100%
rename from examples/services/speech/xai.py
rename to examples/services/xai.py
diff --git a/examples/services/speech/xtts.py b/examples/services/xtts.py
similarity index 100%
rename from examples/services/speech/xtts.py
rename to examples/services/xtts.py
diff --git a/scripts/evals/run-release-evals.py b/scripts/evals/run-release-evals.py
index 3c540ff87..38cde2b11 100644
--- a/scripts/evals/run-release-evals.py
+++ b/scripts/evals/run-release-evals.py
@@ -97,60 +97,60 @@ EVAL_COMPLETE_TURN = EvalConfig(
TESTS_SPEECH = [
- ("services/speech/cartesia.py", EVAL_SIMPLE_MATH),
- ("services/speech/cartesia-http.py", EVAL_SIMPLE_MATH),
- ("services/speech/speechmatics.py", EVAL_SIMPLE_MATH),
- ("services/speech/speechmatics-vad.py", EVAL_SIMPLE_MATH),
- ("services/speech/langchain.py", EVAL_SIMPLE_MATH),
- ("services/speech/deepgram.py", EVAL_SIMPLE_MATH),
- ("services/speech/deepgram-flux.py", EVAL_SIMPLE_MATH),
- ("services/speech/deepgram-http.py", EVAL_SIMPLE_MATH),
- ("services/speech/elevenlabs.py", EVAL_SIMPLE_MATH),
- ("services/speech/elevenlabs-http.py", EVAL_SIMPLE_MATH),
- ("services/speech/xai.py", EVAL_SIMPLE_MATH),
- ("services/speech/azure.py", EVAL_SIMPLE_MATH),
- ("services/speech/azure-http.py", EVAL_SIMPLE_MATH),
- ("services/speech/openai.py", EVAL_SIMPLE_MATH),
- ("services/speech/openai-http.py", EVAL_SIMPLE_MATH),
- ("services/speech/gladia.py", EVAL_SIMPLE_MATH),
- ("services/speech/gladia-vad.py", EVAL_SIMPLE_MATH),
- ("services/speech/lmnt.py", EVAL_SIMPLE_MATH),
- ("services/speech/groq.py", EVAL_SIMPLE_MATH),
- ("services/speech/aws.py", EVAL_SIMPLE_MATH),
- ("services/speech/aws-strands.py", EVAL_WEATHER),
- ("services/speech/google-gemini-tts.py", EVAL_SIMPLE_MATH),
- ("services/speech/google.py", EVAL_SIMPLE_MATH),
- ("services/speech/google-http.py", EVAL_SIMPLE_MATH),
- ("services/speech/assemblyai.py", EVAL_SIMPLE_MATH),
- ("services/speech/krisp-viva.py", EVAL_SIMPLE_MATH),
- ("services/speech/rime.py", EVAL_SIMPLE_MATH),
- ("services/speech/rime-http.py", EVAL_SIMPLE_MATH),
- ("services/speech/nvidia.py", EVAL_SIMPLE_MATH),
- ("services/speech/google-audio-in.py", EVAL_SIMPLE_MATH),
- ("services/speech/fish.py", EVAL_SIMPLE_MATH),
- ("services/speech/neuphonic.py", EVAL_SIMPLE_MATH),
- ("services/speech/neuphonic-http.py", EVAL_SIMPLE_MATH),
- ("services/speech/fal.py", EVAL_SIMPLE_MATH),
- ("services/speech/minimax.py", EVAL_SIMPLE_MATH),
- ("services/speech/sarvam.py", EVAL_SIMPLE_MATH),
- ("services/speech/sarvam-http.py", EVAL_SIMPLE_MATH),
- ("services/speech/soniox.py", EVAL_SIMPLE_MATH),
- ("services/speech/inworld.py", EVAL_SIMPLE_MATH),
- ("services/speech/inworld-http.py", EVAL_SIMPLE_MATH),
- ("services/speech/asyncai.py", EVAL_SIMPLE_MATH),
- ("services/speech/asyncai-http.py", EVAL_SIMPLE_MATH),
- ("services/speech/aicoustics.py", EVAL_SIMPLE_MATH),
- ("services/speech/hume.py", EVAL_SIMPLE_MATH),
- ("services/speech/gradium.py", EVAL_SIMPLE_MATH),
- ("services/speech/camb.py", EVAL_SIMPLE_MATH),
- ("services/speech/piper.py", EVAL_SIMPLE_MATH),
- ("services/speech/kokoro.py", EVAL_SIMPLE_MATH),
- ("services/speech/resemble.py", EVAL_SIMPLE_MATH),
- ("services/speech/smallest.py", EVAL_SIMPLE_MATH),
- ("services/speech/openai-responses.py", EVAL_SIMPLE_MATH),
- ("services/speech/openai-responses-http.py", EVAL_SIMPLE_MATH),
+ ("services/cartesia.py", EVAL_SIMPLE_MATH),
+ ("services/cartesia-http.py", EVAL_SIMPLE_MATH),
+ ("services/speechmatics.py", EVAL_SIMPLE_MATH),
+ ("services/speechmatics-vad.py", EVAL_SIMPLE_MATH),
+ ("services/langchain.py", EVAL_SIMPLE_MATH),
+ ("services/deepgram.py", EVAL_SIMPLE_MATH),
+ ("services/deepgram-flux.py", EVAL_SIMPLE_MATH),
+ ("services/deepgram-http.py", EVAL_SIMPLE_MATH),
+ ("services/elevenlabs.py", EVAL_SIMPLE_MATH),
+ ("services/elevenlabs-http.py", EVAL_SIMPLE_MATH),
+ ("services/xai.py", EVAL_SIMPLE_MATH),
+ ("services/azure.py", EVAL_SIMPLE_MATH),
+ ("services/azure-http.py", EVAL_SIMPLE_MATH),
+ ("services/openai.py", EVAL_SIMPLE_MATH),
+ ("services/openai-http.py", EVAL_SIMPLE_MATH),
+ ("services/gladia.py", EVAL_SIMPLE_MATH),
+ ("services/gladia-vad.py", EVAL_SIMPLE_MATH),
+ ("services/lmnt.py", EVAL_SIMPLE_MATH),
+ ("services/groq.py", EVAL_SIMPLE_MATH),
+ ("services/aws.py", EVAL_SIMPLE_MATH),
+ ("services/aws-strands.py", EVAL_WEATHER),
+ ("services/google-gemini-tts.py", EVAL_SIMPLE_MATH),
+ ("services/google.py", EVAL_SIMPLE_MATH),
+ ("services/google-http.py", EVAL_SIMPLE_MATH),
+ ("services/assemblyai.py", EVAL_SIMPLE_MATH),
+ ("services/krisp-viva.py", EVAL_SIMPLE_MATH),
+ ("services/rime.py", EVAL_SIMPLE_MATH),
+ ("services/rime-http.py", EVAL_SIMPLE_MATH),
+ ("services/nvidia.py", EVAL_SIMPLE_MATH),
+ ("services/google-audio-in.py", EVAL_SIMPLE_MATH),
+ ("services/fish.py", EVAL_SIMPLE_MATH),
+ ("services/neuphonic.py", EVAL_SIMPLE_MATH),
+ ("services/neuphonic-http.py", EVAL_SIMPLE_MATH),
+ ("services/fal.py", EVAL_SIMPLE_MATH),
+ ("services/minimax.py", EVAL_SIMPLE_MATH),
+ ("services/sarvam.py", EVAL_SIMPLE_MATH),
+ ("services/sarvam-http.py", EVAL_SIMPLE_MATH),
+ ("services/soniox.py", EVAL_SIMPLE_MATH),
+ ("services/inworld.py", EVAL_SIMPLE_MATH),
+ ("services/inworld-http.py", EVAL_SIMPLE_MATH),
+ ("services/asyncai.py", EVAL_SIMPLE_MATH),
+ ("services/asyncai-http.py", EVAL_SIMPLE_MATH),
+ ("services/aicoustics.py", EVAL_SIMPLE_MATH),
+ ("services/hume.py", EVAL_SIMPLE_MATH),
+ ("services/gradium.py", EVAL_SIMPLE_MATH),
+ ("services/camb.py", EVAL_SIMPLE_MATH),
+ ("services/piper.py", EVAL_SIMPLE_MATH),
+ ("services/kokoro.py", EVAL_SIMPLE_MATH),
+ ("services/resemble.py", EVAL_SIMPLE_MATH),
+ ("services/smallest.py", EVAL_SIMPLE_MATH),
+ ("services/openai-responses.py", EVAL_SIMPLE_MATH),
+ ("services/openai-responses-http.py", EVAL_SIMPLE_MATH),
# Needs a local XTTS docker instance running.
- # ("services/speech/xtts.py", EVAL_SIMPLE_MATH),
+ # ("services/xtts.py", EVAL_SIMPLE_MATH),
]
TESTS_VISION = [
@@ -169,44 +169,44 @@ TESTS_VISION = [
TESTS_FUNCTION_CALLING = [
("getting-started/07-function-calling.py", EVAL_WEATHER),
("getting-started/07-function-calling.py", EVAL_WEATHER_AND_RESTAURANT),
- ("services/function-calling/openai-responses.py", EVAL_WEATHER),
- ("services/function-calling/openai-responses.py", EVAL_WEATHER_AND_RESTAURANT),
- ("services/function-calling/openai-responses-http.py", EVAL_WEATHER),
- ("services/function-calling/openai-responses-http.py", EVAL_WEATHER_AND_RESTAURANT),
- ("services/function-calling/anthropic.py", EVAL_WEATHER),
- ("services/function-calling/anthropic.py", EVAL_WEATHER_AND_RESTAURANT),
- ("services/function-calling/openai.py", EVAL_WEATHER),
- ("services/function-calling/google.py", EVAL_WEATHER),
- ("services/function-calling/google.py", EVAL_WEATHER_AND_RESTAURANT),
- ("services/function-calling/groq.py", EVAL_WEATHER),
- ("services/function-calling/grok.py", EVAL_WEATHER),
- ("services/function-calling/azure.py", EVAL_WEATHER),
- ("services/function-calling/fireworks.py", EVAL_WEATHER),
- ("services/function-calling/nvidia.py", EVAL_WEATHER),
- ("services/function-calling/cerebras.py", EVAL_WEATHER),
- ("services/function-calling/openrouter.py", EVAL_WEATHER),
- ("services/function-calling/perplexity.py", EVAL_WEATHER),
- ("services/function-calling/google-vertex.py", EVAL_WEATHER),
- ("services/function-calling/qwen.py", EVAL_WEATHER),
- ("services/function-calling/aws.py", EVAL_WEATHER),
- ("services/function-calling/sambanova.py", EVAL_WEATHER),
- ("services/function-calling/aws.py", EVAL_WEATHER_AND_RESTAURANT),
- ("services/function-calling/nebius.py", EVAL_WEATHER),
- ("services/function-calling/mistral.py", EVAL_WEATHER),
- ("services/function-calling/sarvam.py", EVAL_WEATHER),
- ("services/function-calling/novita.py", EVAL_WEATHER),
+ ("function-calling/openai-responses.py", EVAL_WEATHER),
+ ("function-calling/openai-responses.py", EVAL_WEATHER_AND_RESTAURANT),
+ ("function-calling/openai-responses-http.py", EVAL_WEATHER),
+ ("function-calling/openai-responses-http.py", EVAL_WEATHER_AND_RESTAURANT),
+ ("function-calling/anthropic.py", EVAL_WEATHER),
+ ("function-calling/anthropic.py", EVAL_WEATHER_AND_RESTAURANT),
+ ("function-calling/openai.py", EVAL_WEATHER),
+ ("function-calling/google.py", EVAL_WEATHER),
+ ("function-calling/google.py", EVAL_WEATHER_AND_RESTAURANT),
+ ("function-calling/groq.py", EVAL_WEATHER),
+ ("function-calling/grok.py", EVAL_WEATHER),
+ ("function-calling/azure.py", EVAL_WEATHER),
+ ("function-calling/fireworks.py", EVAL_WEATHER),
+ ("function-calling/nvidia.py", EVAL_WEATHER),
+ ("function-calling/cerebras.py", EVAL_WEATHER),
+ ("function-calling/openrouter.py", EVAL_WEATHER),
+ ("function-calling/perplexity.py", EVAL_WEATHER),
+ ("function-calling/google-vertex.py", EVAL_WEATHER),
+ ("function-calling/qwen.py", EVAL_WEATHER),
+ ("function-calling/aws.py", EVAL_WEATHER),
+ ("function-calling/sambanova.py", EVAL_WEATHER),
+ ("function-calling/aws.py", EVAL_WEATHER_AND_RESTAURANT),
+ ("function-calling/nebius.py", EVAL_WEATHER),
+ ("function-calling/mistral.py", EVAL_WEATHER),
+ ("function-calling/sarvam.py", EVAL_WEATHER),
+ ("function-calling/novita.py", EVAL_WEATHER),
# Video
- ("services/function-calling/anthropic-video.py", EVAL_VISION_CAMERA),
- ("services/function-calling/aws-video.py", EVAL_VISION_CAMERA),
- ("services/function-calling/google-video.py", EVAL_VISION_CAMERA),
- ("services/function-calling/moondream-video.py", EVAL_VISION_CAMERA),
- ("services/function-calling/openai-video.py", EVAL_VISION_CAMERA),
- ("services/function-calling/openai-responses-video.py", EVAL_VISION_CAMERA),
- ("services/function-calling/openai-responses-video-http.py", EVAL_VISION_CAMERA),
+ ("function-calling/anthropic-video.py", EVAL_VISION_CAMERA),
+ ("function-calling/aws-video.py", EVAL_VISION_CAMERA),
+ ("function-calling/google-video.py", EVAL_VISION_CAMERA),
+ ("function-calling/moondream-video.py", EVAL_VISION_CAMERA),
+ ("function-calling/openai-video.py", EVAL_VISION_CAMERA),
+ ("function-calling/openai-responses-video.py", EVAL_VISION_CAMERA),
+ ("function-calling/openai-responses-video-http.py", EVAL_VISION_CAMERA),
# Currently not working.
- # ("services/function-calling/together.py", EVAL_WEATHER),
- # ("services/function-calling/deepseek.py", EVAL_WEATHER),
- # ("services/function-calling/gemini-openai-format.py", EVAL_WEATHER),
+ # ("function-calling/together.py", EVAL_WEATHER),
+ # ("function-calling/deepseek.py", EVAL_WEATHER),
+ # ("function-calling/gemini-openai-format.py", EVAL_WEATHER),
]
TESTS_FEATURES = [
From f14638a1fdab61b6c3218a2b2b45e868356615df Mon Sep 17 00:00:00 2001
From: Mark Backman
Date: Tue, 31 Mar 2026 14:59:23 -0400
Subject: [PATCH 11/19] Revert "Flatten services/ nesting: promote speech and
function-calling to top level"
This reverts commit e1939ecd4447bbe1cd1a81f3c72f9810420db5de.
---
examples/README.md | 7 +-
.../function-calling/anthropic-video.py | 0
.../function-calling/anthropic.py | 0
.../function-calling/aws-video.py | 0
.../{ => services}/function-calling/aws.py | 0
.../{ => services}/function-calling/azure.py | 0
.../function-calling/cerebras.py | 0
.../function-calling/deepseek.py | 0
.../{ => services}/function-calling/direct.py | 0
.../function-calling/fireworks.py | 0
.../function-calling/gemini-openai-format.py | 0
.../function-calling/google-vertex-ai.py | 0
.../function-calling/google-video.py | 0
.../{ => services}/function-calling/google.py | 0
.../{ => services}/function-calling/grok.py | 0
.../{ => services}/function-calling/groq.py | 0
.../function-calling/mistral.py | 0
.../function-calling/moondream-video.py | 0
.../{ => services}/function-calling/nebius.py | 0
.../{ => services}/function-calling/novita.py | 0
.../{ => services}/function-calling/nvidia.py | 0
.../{ => services}/function-calling/ollama.py | 0
.../function-calling/openai-responses-http.py | 0
.../openai-responses-video-http.py | 0
.../openai-responses-video.py | 0
.../function-calling/openai-responses.py | 0
.../function-calling/openai-video.py | 0
.../{ => services}/function-calling/openai.py | 0
.../function-calling/openrouter.py | 0
.../function-calling/perplexity.py | 0
.../{ => services}/function-calling/qwen.py | 0
.../function-calling/sambanova.py | 0
.../{ => services}/function-calling/sarvam.py | 0
.../function-calling/together.py | 0
examples/services/{ => speech}/aicoustics.py | 0
.../{ => speech}/assemblyai-turn-detection.py | 0
examples/services/{ => speech}/assemblyai.py | 0
.../services/{ => speech}/asyncai-http.py | 0
examples/services/{ => speech}/asyncai.py | 0
examples/services/{ => speech}/aws-strands.py | 0
examples/services/{ => speech}/aws.py | 0
examples/services/{ => speech}/azure-http.py | 0
examples/services/{ => speech}/azure.py | 0
examples/services/{ => speech}/camb.py | 0
.../services/{ => speech}/cartesia-http.py | 0
examples/services/{ => speech}/cartesia.py | 0
.../{ => speech}/deepgram-flux-sagemaker.py | 0
.../services/{ => speech}/deepgram-flux.py | 0
.../services/{ => speech}/deepgram-http.py | 0
.../{ => speech}/deepgram-sagemaker.py | 0
.../services/{ => speech}/deepgram-vad.py | 0
examples/services/{ => speech}/deepgram.py | 0
.../services/{ => speech}/elevenlabs-http.py | 0
examples/services/{ => speech}/elevenlabs.py | 0
examples/services/{ => speech}/fal.py | 0
examples/services/{ => speech}/fish.py | 0
examples/services/{ => speech}/gladia-vad.py | 0
examples/services/{ => speech}/gladia.py | 0
.../services/{ => speech}/google-audio-in.py | 0
.../{ => speech}/google-gemini-tts.py | 0
examples/services/{ => speech}/google-http.py | 0
.../services/{ => speech}/google-image.py | 0
examples/services/{ => speech}/google.py | 0
examples/services/{ => speech}/gradium.py | 0
examples/services/{ => speech}/groq.py | 0
examples/services/{ => speech}/hume.py | 0
.../services/{ => speech}/inworld-http.py | 0
examples/services/{ => speech}/inworld.py | 0
examples/services/{ => speech}/kokoro.py | 0
examples/services/{ => speech}/krisp-viva.py | 0
examples/services/{ => speech}/langchain.py | 0
examples/services/{ => speech}/lmnt.py | 0
examples/services/{ => speech}/minimax.py | 0
.../services/{ => speech}/neuphonic-http.py | 0
examples/services/{ => speech}/neuphonic.py | 0
examples/services/{ => speech}/nvidia.py | 0
examples/services/{ => speech}/openai-http.py | 0
.../{ => speech}/openai-responses-http.py | 0
.../services/{ => speech}/openai-responses.py | 0
examples/services/{ => speech}/openai.py | 0
examples/services/{ => speech}/piper.py | 0
examples/services/{ => speech}/resemble.py | 0
examples/services/{ => speech}/rime-http.py | 0
examples/services/{ => speech}/rime.py | 0
examples/services/{ => speech}/sarvam-http.py | 0
examples/services/{ => speech}/sarvam.py | 0
examples/services/{ => speech}/smallest.py | 0
examples/services/{ => speech}/soniox.py | 0
.../services/{ => speech}/speechmatics-vad.py | 0
.../services/{ => speech}/speechmatics.py | 0
examples/services/{ => speech}/xai.py | 0
examples/services/{ => speech}/xtts.py | 0
scripts/evals/run-release-evals.py | 178 +++++++++---------
93 files changed, 92 insertions(+), 93 deletions(-)
rename examples/{ => services}/function-calling/anthropic-video.py (100%)
rename examples/{ => services}/function-calling/anthropic.py (100%)
rename examples/{ => services}/function-calling/aws-video.py (100%)
rename examples/{ => services}/function-calling/aws.py (100%)
rename examples/{ => services}/function-calling/azure.py (100%)
rename examples/{ => services}/function-calling/cerebras.py (100%)
rename examples/{ => services}/function-calling/deepseek.py (100%)
rename examples/{ => services}/function-calling/direct.py (100%)
rename examples/{ => services}/function-calling/fireworks.py (100%)
rename examples/{ => services}/function-calling/gemini-openai-format.py (100%)
rename examples/{ => services}/function-calling/google-vertex-ai.py (100%)
rename examples/{ => services}/function-calling/google-video.py (100%)
rename examples/{ => services}/function-calling/google.py (100%)
rename examples/{ => services}/function-calling/grok.py (100%)
rename examples/{ => services}/function-calling/groq.py (100%)
rename examples/{ => services}/function-calling/mistral.py (100%)
rename examples/{ => services}/function-calling/moondream-video.py (100%)
rename examples/{ => services}/function-calling/nebius.py (100%)
rename examples/{ => services}/function-calling/novita.py (100%)
rename examples/{ => services}/function-calling/nvidia.py (100%)
rename examples/{ => services}/function-calling/ollama.py (100%)
rename examples/{ => services}/function-calling/openai-responses-http.py (100%)
rename examples/{ => services}/function-calling/openai-responses-video-http.py (100%)
rename examples/{ => services}/function-calling/openai-responses-video.py (100%)
rename examples/{ => services}/function-calling/openai-responses.py (100%)
rename examples/{ => services}/function-calling/openai-video.py (100%)
rename examples/{ => services}/function-calling/openai.py (100%)
rename examples/{ => services}/function-calling/openrouter.py (100%)
rename examples/{ => services}/function-calling/perplexity.py (100%)
rename examples/{ => services}/function-calling/qwen.py (100%)
rename examples/{ => services}/function-calling/sambanova.py (100%)
rename examples/{ => services}/function-calling/sarvam.py (100%)
rename examples/{ => services}/function-calling/together.py (100%)
rename examples/services/{ => speech}/aicoustics.py (100%)
rename examples/services/{ => speech}/assemblyai-turn-detection.py (100%)
rename examples/services/{ => speech}/assemblyai.py (100%)
rename examples/services/{ => speech}/asyncai-http.py (100%)
rename examples/services/{ => speech}/asyncai.py (100%)
rename examples/services/{ => speech}/aws-strands.py (100%)
rename examples/services/{ => speech}/aws.py (100%)
rename examples/services/{ => speech}/azure-http.py (100%)
rename examples/services/{ => speech}/azure.py (100%)
rename examples/services/{ => speech}/camb.py (100%)
rename examples/services/{ => speech}/cartesia-http.py (100%)
rename examples/services/{ => speech}/cartesia.py (100%)
rename examples/services/{ => speech}/deepgram-flux-sagemaker.py (100%)
rename examples/services/{ => speech}/deepgram-flux.py (100%)
rename examples/services/{ => speech}/deepgram-http.py (100%)
rename examples/services/{ => speech}/deepgram-sagemaker.py (100%)
rename examples/services/{ => speech}/deepgram-vad.py (100%)
rename examples/services/{ => speech}/deepgram.py (100%)
rename examples/services/{ => speech}/elevenlabs-http.py (100%)
rename examples/services/{ => speech}/elevenlabs.py (100%)
rename examples/services/{ => speech}/fal.py (100%)
rename examples/services/{ => speech}/fish.py (100%)
rename examples/services/{ => speech}/gladia-vad.py (100%)
rename examples/services/{ => speech}/gladia.py (100%)
rename examples/services/{ => speech}/google-audio-in.py (100%)
rename examples/services/{ => speech}/google-gemini-tts.py (100%)
rename examples/services/{ => speech}/google-http.py (100%)
rename examples/services/{ => speech}/google-image.py (100%)
rename examples/services/{ => speech}/google.py (100%)
rename examples/services/{ => speech}/gradium.py (100%)
rename examples/services/{ => speech}/groq.py (100%)
rename examples/services/{ => speech}/hume.py (100%)
rename examples/services/{ => speech}/inworld-http.py (100%)
rename examples/services/{ => speech}/inworld.py (100%)
rename examples/services/{ => speech}/kokoro.py (100%)
rename examples/services/{ => speech}/krisp-viva.py (100%)
rename examples/services/{ => speech}/langchain.py (100%)
rename examples/services/{ => speech}/lmnt.py (100%)
rename examples/services/{ => speech}/minimax.py (100%)
rename examples/services/{ => speech}/neuphonic-http.py (100%)
rename examples/services/{ => speech}/neuphonic.py (100%)
rename examples/services/{ => speech}/nvidia.py (100%)
rename examples/services/{ => speech}/openai-http.py (100%)
rename examples/services/{ => speech}/openai-responses-http.py (100%)
rename examples/services/{ => speech}/openai-responses.py (100%)
rename examples/services/{ => speech}/openai.py (100%)
rename examples/services/{ => speech}/piper.py (100%)
rename examples/services/{ => speech}/resemble.py (100%)
rename examples/services/{ => speech}/rime-http.py (100%)
rename examples/services/{ => speech}/rime.py (100%)
rename examples/services/{ => speech}/sarvam-http.py (100%)
rename examples/services/{ => speech}/sarvam.py (100%)
rename examples/services/{ => speech}/smallest.py (100%)
rename examples/services/{ => speech}/soniox.py (100%)
rename examples/services/{ => speech}/speechmatics-vad.py (100%)
rename examples/services/{ => speech}/speechmatics.py (100%)
rename examples/services/{ => speech}/xai.py (100%)
rename examples/services/{ => speech}/xtts.py (100%)
diff --git a/examples/README.md b/examples/README.md
index a7fabaa73..08dc58de5 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -63,11 +63,10 @@ Progressive introduction to Pipecat, from minimal TTS to a full voice agent with
### [`services/`](./services/)
-Full STT + LLM + TTS pipelines showcasing different speech service providers (Deepgram, ElevenLabs, Cartesia, etc.)
+Service provider integration examples, organized into subfolders:
-### [`function-calling/`](./function-calling/)
-
-Function calling with different LLM providers (OpenAI, Anthropic, Google, etc.)
+- **[`speech/`](./services/speech/)** — Full STT + LLM + TTS pipelines showcasing different speech service providers (Deepgram, ElevenLabs, Cartesia, etc.)
+- **[`function-calling/`](./services/function-calling/)** — Function calling with different LLM providers (OpenAI, Anthropic, Google, etc.)
### [`transcription/`](./transcription/)
diff --git a/examples/function-calling/anthropic-video.py b/examples/services/function-calling/anthropic-video.py
similarity index 100%
rename from examples/function-calling/anthropic-video.py
rename to examples/services/function-calling/anthropic-video.py
diff --git a/examples/function-calling/anthropic.py b/examples/services/function-calling/anthropic.py
similarity index 100%
rename from examples/function-calling/anthropic.py
rename to examples/services/function-calling/anthropic.py
diff --git a/examples/function-calling/aws-video.py b/examples/services/function-calling/aws-video.py
similarity index 100%
rename from examples/function-calling/aws-video.py
rename to examples/services/function-calling/aws-video.py
diff --git a/examples/function-calling/aws.py b/examples/services/function-calling/aws.py
similarity index 100%
rename from examples/function-calling/aws.py
rename to examples/services/function-calling/aws.py
diff --git a/examples/function-calling/azure.py b/examples/services/function-calling/azure.py
similarity index 100%
rename from examples/function-calling/azure.py
rename to examples/services/function-calling/azure.py
diff --git a/examples/function-calling/cerebras.py b/examples/services/function-calling/cerebras.py
similarity index 100%
rename from examples/function-calling/cerebras.py
rename to examples/services/function-calling/cerebras.py
diff --git a/examples/function-calling/deepseek.py b/examples/services/function-calling/deepseek.py
similarity index 100%
rename from examples/function-calling/deepseek.py
rename to examples/services/function-calling/deepseek.py
diff --git a/examples/function-calling/direct.py b/examples/services/function-calling/direct.py
similarity index 100%
rename from examples/function-calling/direct.py
rename to examples/services/function-calling/direct.py
diff --git a/examples/function-calling/fireworks.py b/examples/services/function-calling/fireworks.py
similarity index 100%
rename from examples/function-calling/fireworks.py
rename to examples/services/function-calling/fireworks.py
diff --git a/examples/function-calling/gemini-openai-format.py b/examples/services/function-calling/gemini-openai-format.py
similarity index 100%
rename from examples/function-calling/gemini-openai-format.py
rename to examples/services/function-calling/gemini-openai-format.py
diff --git a/examples/function-calling/google-vertex-ai.py b/examples/services/function-calling/google-vertex-ai.py
similarity index 100%
rename from examples/function-calling/google-vertex-ai.py
rename to examples/services/function-calling/google-vertex-ai.py
diff --git a/examples/function-calling/google-video.py b/examples/services/function-calling/google-video.py
similarity index 100%
rename from examples/function-calling/google-video.py
rename to examples/services/function-calling/google-video.py
diff --git a/examples/function-calling/google.py b/examples/services/function-calling/google.py
similarity index 100%
rename from examples/function-calling/google.py
rename to examples/services/function-calling/google.py
diff --git a/examples/function-calling/grok.py b/examples/services/function-calling/grok.py
similarity index 100%
rename from examples/function-calling/grok.py
rename to examples/services/function-calling/grok.py
diff --git a/examples/function-calling/groq.py b/examples/services/function-calling/groq.py
similarity index 100%
rename from examples/function-calling/groq.py
rename to examples/services/function-calling/groq.py
diff --git a/examples/function-calling/mistral.py b/examples/services/function-calling/mistral.py
similarity index 100%
rename from examples/function-calling/mistral.py
rename to examples/services/function-calling/mistral.py
diff --git a/examples/function-calling/moondream-video.py b/examples/services/function-calling/moondream-video.py
similarity index 100%
rename from examples/function-calling/moondream-video.py
rename to examples/services/function-calling/moondream-video.py
diff --git a/examples/function-calling/nebius.py b/examples/services/function-calling/nebius.py
similarity index 100%
rename from examples/function-calling/nebius.py
rename to examples/services/function-calling/nebius.py
diff --git a/examples/function-calling/novita.py b/examples/services/function-calling/novita.py
similarity index 100%
rename from examples/function-calling/novita.py
rename to examples/services/function-calling/novita.py
diff --git a/examples/function-calling/nvidia.py b/examples/services/function-calling/nvidia.py
similarity index 100%
rename from examples/function-calling/nvidia.py
rename to examples/services/function-calling/nvidia.py
diff --git a/examples/function-calling/ollama.py b/examples/services/function-calling/ollama.py
similarity index 100%
rename from examples/function-calling/ollama.py
rename to examples/services/function-calling/ollama.py
diff --git a/examples/function-calling/openai-responses-http.py b/examples/services/function-calling/openai-responses-http.py
similarity index 100%
rename from examples/function-calling/openai-responses-http.py
rename to examples/services/function-calling/openai-responses-http.py
diff --git a/examples/function-calling/openai-responses-video-http.py b/examples/services/function-calling/openai-responses-video-http.py
similarity index 100%
rename from examples/function-calling/openai-responses-video-http.py
rename to examples/services/function-calling/openai-responses-video-http.py
diff --git a/examples/function-calling/openai-responses-video.py b/examples/services/function-calling/openai-responses-video.py
similarity index 100%
rename from examples/function-calling/openai-responses-video.py
rename to examples/services/function-calling/openai-responses-video.py
diff --git a/examples/function-calling/openai-responses.py b/examples/services/function-calling/openai-responses.py
similarity index 100%
rename from examples/function-calling/openai-responses.py
rename to examples/services/function-calling/openai-responses.py
diff --git a/examples/function-calling/openai-video.py b/examples/services/function-calling/openai-video.py
similarity index 100%
rename from examples/function-calling/openai-video.py
rename to examples/services/function-calling/openai-video.py
diff --git a/examples/function-calling/openai.py b/examples/services/function-calling/openai.py
similarity index 100%
rename from examples/function-calling/openai.py
rename to examples/services/function-calling/openai.py
diff --git a/examples/function-calling/openrouter.py b/examples/services/function-calling/openrouter.py
similarity index 100%
rename from examples/function-calling/openrouter.py
rename to examples/services/function-calling/openrouter.py
diff --git a/examples/function-calling/perplexity.py b/examples/services/function-calling/perplexity.py
similarity index 100%
rename from examples/function-calling/perplexity.py
rename to examples/services/function-calling/perplexity.py
diff --git a/examples/function-calling/qwen.py b/examples/services/function-calling/qwen.py
similarity index 100%
rename from examples/function-calling/qwen.py
rename to examples/services/function-calling/qwen.py
diff --git a/examples/function-calling/sambanova.py b/examples/services/function-calling/sambanova.py
similarity index 100%
rename from examples/function-calling/sambanova.py
rename to examples/services/function-calling/sambanova.py
diff --git a/examples/function-calling/sarvam.py b/examples/services/function-calling/sarvam.py
similarity index 100%
rename from examples/function-calling/sarvam.py
rename to examples/services/function-calling/sarvam.py
diff --git a/examples/function-calling/together.py b/examples/services/function-calling/together.py
similarity index 100%
rename from examples/function-calling/together.py
rename to examples/services/function-calling/together.py
diff --git a/examples/services/aicoustics.py b/examples/services/speech/aicoustics.py
similarity index 100%
rename from examples/services/aicoustics.py
rename to examples/services/speech/aicoustics.py
diff --git a/examples/services/assemblyai-turn-detection.py b/examples/services/speech/assemblyai-turn-detection.py
similarity index 100%
rename from examples/services/assemblyai-turn-detection.py
rename to examples/services/speech/assemblyai-turn-detection.py
diff --git a/examples/services/assemblyai.py b/examples/services/speech/assemblyai.py
similarity index 100%
rename from examples/services/assemblyai.py
rename to examples/services/speech/assemblyai.py
diff --git a/examples/services/asyncai-http.py b/examples/services/speech/asyncai-http.py
similarity index 100%
rename from examples/services/asyncai-http.py
rename to examples/services/speech/asyncai-http.py
diff --git a/examples/services/asyncai.py b/examples/services/speech/asyncai.py
similarity index 100%
rename from examples/services/asyncai.py
rename to examples/services/speech/asyncai.py
diff --git a/examples/services/aws-strands.py b/examples/services/speech/aws-strands.py
similarity index 100%
rename from examples/services/aws-strands.py
rename to examples/services/speech/aws-strands.py
diff --git a/examples/services/aws.py b/examples/services/speech/aws.py
similarity index 100%
rename from examples/services/aws.py
rename to examples/services/speech/aws.py
diff --git a/examples/services/azure-http.py b/examples/services/speech/azure-http.py
similarity index 100%
rename from examples/services/azure-http.py
rename to examples/services/speech/azure-http.py
diff --git a/examples/services/azure.py b/examples/services/speech/azure.py
similarity index 100%
rename from examples/services/azure.py
rename to examples/services/speech/azure.py
diff --git a/examples/services/camb.py b/examples/services/speech/camb.py
similarity index 100%
rename from examples/services/camb.py
rename to examples/services/speech/camb.py
diff --git a/examples/services/cartesia-http.py b/examples/services/speech/cartesia-http.py
similarity index 100%
rename from examples/services/cartesia-http.py
rename to examples/services/speech/cartesia-http.py
diff --git a/examples/services/cartesia.py b/examples/services/speech/cartesia.py
similarity index 100%
rename from examples/services/cartesia.py
rename to examples/services/speech/cartesia.py
diff --git a/examples/services/deepgram-flux-sagemaker.py b/examples/services/speech/deepgram-flux-sagemaker.py
similarity index 100%
rename from examples/services/deepgram-flux-sagemaker.py
rename to examples/services/speech/deepgram-flux-sagemaker.py
diff --git a/examples/services/deepgram-flux.py b/examples/services/speech/deepgram-flux.py
similarity index 100%
rename from examples/services/deepgram-flux.py
rename to examples/services/speech/deepgram-flux.py
diff --git a/examples/services/deepgram-http.py b/examples/services/speech/deepgram-http.py
similarity index 100%
rename from examples/services/deepgram-http.py
rename to examples/services/speech/deepgram-http.py
diff --git a/examples/services/deepgram-sagemaker.py b/examples/services/speech/deepgram-sagemaker.py
similarity index 100%
rename from examples/services/deepgram-sagemaker.py
rename to examples/services/speech/deepgram-sagemaker.py
diff --git a/examples/services/deepgram-vad.py b/examples/services/speech/deepgram-vad.py
similarity index 100%
rename from examples/services/deepgram-vad.py
rename to examples/services/speech/deepgram-vad.py
diff --git a/examples/services/deepgram.py b/examples/services/speech/deepgram.py
similarity index 100%
rename from examples/services/deepgram.py
rename to examples/services/speech/deepgram.py
diff --git a/examples/services/elevenlabs-http.py b/examples/services/speech/elevenlabs-http.py
similarity index 100%
rename from examples/services/elevenlabs-http.py
rename to examples/services/speech/elevenlabs-http.py
diff --git a/examples/services/elevenlabs.py b/examples/services/speech/elevenlabs.py
similarity index 100%
rename from examples/services/elevenlabs.py
rename to examples/services/speech/elevenlabs.py
diff --git a/examples/services/fal.py b/examples/services/speech/fal.py
similarity index 100%
rename from examples/services/fal.py
rename to examples/services/speech/fal.py
diff --git a/examples/services/fish.py b/examples/services/speech/fish.py
similarity index 100%
rename from examples/services/fish.py
rename to examples/services/speech/fish.py
diff --git a/examples/services/gladia-vad.py b/examples/services/speech/gladia-vad.py
similarity index 100%
rename from examples/services/gladia-vad.py
rename to examples/services/speech/gladia-vad.py
diff --git a/examples/services/gladia.py b/examples/services/speech/gladia.py
similarity index 100%
rename from examples/services/gladia.py
rename to examples/services/speech/gladia.py
diff --git a/examples/services/google-audio-in.py b/examples/services/speech/google-audio-in.py
similarity index 100%
rename from examples/services/google-audio-in.py
rename to examples/services/speech/google-audio-in.py
diff --git a/examples/services/google-gemini-tts.py b/examples/services/speech/google-gemini-tts.py
similarity index 100%
rename from examples/services/google-gemini-tts.py
rename to examples/services/speech/google-gemini-tts.py
diff --git a/examples/services/google-http.py b/examples/services/speech/google-http.py
similarity index 100%
rename from examples/services/google-http.py
rename to examples/services/speech/google-http.py
diff --git a/examples/services/google-image.py b/examples/services/speech/google-image.py
similarity index 100%
rename from examples/services/google-image.py
rename to examples/services/speech/google-image.py
diff --git a/examples/services/google.py b/examples/services/speech/google.py
similarity index 100%
rename from examples/services/google.py
rename to examples/services/speech/google.py
diff --git a/examples/services/gradium.py b/examples/services/speech/gradium.py
similarity index 100%
rename from examples/services/gradium.py
rename to examples/services/speech/gradium.py
diff --git a/examples/services/groq.py b/examples/services/speech/groq.py
similarity index 100%
rename from examples/services/groq.py
rename to examples/services/speech/groq.py
diff --git a/examples/services/hume.py b/examples/services/speech/hume.py
similarity index 100%
rename from examples/services/hume.py
rename to examples/services/speech/hume.py
diff --git a/examples/services/inworld-http.py b/examples/services/speech/inworld-http.py
similarity index 100%
rename from examples/services/inworld-http.py
rename to examples/services/speech/inworld-http.py
diff --git a/examples/services/inworld.py b/examples/services/speech/inworld.py
similarity index 100%
rename from examples/services/inworld.py
rename to examples/services/speech/inworld.py
diff --git a/examples/services/kokoro.py b/examples/services/speech/kokoro.py
similarity index 100%
rename from examples/services/kokoro.py
rename to examples/services/speech/kokoro.py
diff --git a/examples/services/krisp-viva.py b/examples/services/speech/krisp-viva.py
similarity index 100%
rename from examples/services/krisp-viva.py
rename to examples/services/speech/krisp-viva.py
diff --git a/examples/services/langchain.py b/examples/services/speech/langchain.py
similarity index 100%
rename from examples/services/langchain.py
rename to examples/services/speech/langchain.py
diff --git a/examples/services/lmnt.py b/examples/services/speech/lmnt.py
similarity index 100%
rename from examples/services/lmnt.py
rename to examples/services/speech/lmnt.py
diff --git a/examples/services/minimax.py b/examples/services/speech/minimax.py
similarity index 100%
rename from examples/services/minimax.py
rename to examples/services/speech/minimax.py
diff --git a/examples/services/neuphonic-http.py b/examples/services/speech/neuphonic-http.py
similarity index 100%
rename from examples/services/neuphonic-http.py
rename to examples/services/speech/neuphonic-http.py
diff --git a/examples/services/neuphonic.py b/examples/services/speech/neuphonic.py
similarity index 100%
rename from examples/services/neuphonic.py
rename to examples/services/speech/neuphonic.py
diff --git a/examples/services/nvidia.py b/examples/services/speech/nvidia.py
similarity index 100%
rename from examples/services/nvidia.py
rename to examples/services/speech/nvidia.py
diff --git a/examples/services/openai-http.py b/examples/services/speech/openai-http.py
similarity index 100%
rename from examples/services/openai-http.py
rename to examples/services/speech/openai-http.py
diff --git a/examples/services/openai-responses-http.py b/examples/services/speech/openai-responses-http.py
similarity index 100%
rename from examples/services/openai-responses-http.py
rename to examples/services/speech/openai-responses-http.py
diff --git a/examples/services/openai-responses.py b/examples/services/speech/openai-responses.py
similarity index 100%
rename from examples/services/openai-responses.py
rename to examples/services/speech/openai-responses.py
diff --git a/examples/services/openai.py b/examples/services/speech/openai.py
similarity index 100%
rename from examples/services/openai.py
rename to examples/services/speech/openai.py
diff --git a/examples/services/piper.py b/examples/services/speech/piper.py
similarity index 100%
rename from examples/services/piper.py
rename to examples/services/speech/piper.py
diff --git a/examples/services/resemble.py b/examples/services/speech/resemble.py
similarity index 100%
rename from examples/services/resemble.py
rename to examples/services/speech/resemble.py
diff --git a/examples/services/rime-http.py b/examples/services/speech/rime-http.py
similarity index 100%
rename from examples/services/rime-http.py
rename to examples/services/speech/rime-http.py
diff --git a/examples/services/rime.py b/examples/services/speech/rime.py
similarity index 100%
rename from examples/services/rime.py
rename to examples/services/speech/rime.py
diff --git a/examples/services/sarvam-http.py b/examples/services/speech/sarvam-http.py
similarity index 100%
rename from examples/services/sarvam-http.py
rename to examples/services/speech/sarvam-http.py
diff --git a/examples/services/sarvam.py b/examples/services/speech/sarvam.py
similarity index 100%
rename from examples/services/sarvam.py
rename to examples/services/speech/sarvam.py
diff --git a/examples/services/smallest.py b/examples/services/speech/smallest.py
similarity index 100%
rename from examples/services/smallest.py
rename to examples/services/speech/smallest.py
diff --git a/examples/services/soniox.py b/examples/services/speech/soniox.py
similarity index 100%
rename from examples/services/soniox.py
rename to examples/services/speech/soniox.py
diff --git a/examples/services/speechmatics-vad.py b/examples/services/speech/speechmatics-vad.py
similarity index 100%
rename from examples/services/speechmatics-vad.py
rename to examples/services/speech/speechmatics-vad.py
diff --git a/examples/services/speechmatics.py b/examples/services/speech/speechmatics.py
similarity index 100%
rename from examples/services/speechmatics.py
rename to examples/services/speech/speechmatics.py
diff --git a/examples/services/xai.py b/examples/services/speech/xai.py
similarity index 100%
rename from examples/services/xai.py
rename to examples/services/speech/xai.py
diff --git a/examples/services/xtts.py b/examples/services/speech/xtts.py
similarity index 100%
rename from examples/services/xtts.py
rename to examples/services/speech/xtts.py
diff --git a/scripts/evals/run-release-evals.py b/scripts/evals/run-release-evals.py
index 38cde2b11..3c540ff87 100644
--- a/scripts/evals/run-release-evals.py
+++ b/scripts/evals/run-release-evals.py
@@ -97,60 +97,60 @@ EVAL_COMPLETE_TURN = EvalConfig(
TESTS_SPEECH = [
- ("services/cartesia.py", EVAL_SIMPLE_MATH),
- ("services/cartesia-http.py", EVAL_SIMPLE_MATH),
- ("services/speechmatics.py", EVAL_SIMPLE_MATH),
- ("services/speechmatics-vad.py", EVAL_SIMPLE_MATH),
- ("services/langchain.py", EVAL_SIMPLE_MATH),
- ("services/deepgram.py", EVAL_SIMPLE_MATH),
- ("services/deepgram-flux.py", EVAL_SIMPLE_MATH),
- ("services/deepgram-http.py", EVAL_SIMPLE_MATH),
- ("services/elevenlabs.py", EVAL_SIMPLE_MATH),
- ("services/elevenlabs-http.py", EVAL_SIMPLE_MATH),
- ("services/xai.py", EVAL_SIMPLE_MATH),
- ("services/azure.py", EVAL_SIMPLE_MATH),
- ("services/azure-http.py", EVAL_SIMPLE_MATH),
- ("services/openai.py", EVAL_SIMPLE_MATH),
- ("services/openai-http.py", EVAL_SIMPLE_MATH),
- ("services/gladia.py", EVAL_SIMPLE_MATH),
- ("services/gladia-vad.py", EVAL_SIMPLE_MATH),
- ("services/lmnt.py", EVAL_SIMPLE_MATH),
- ("services/groq.py", EVAL_SIMPLE_MATH),
- ("services/aws.py", EVAL_SIMPLE_MATH),
- ("services/aws-strands.py", EVAL_WEATHER),
- ("services/google-gemini-tts.py", EVAL_SIMPLE_MATH),
- ("services/google.py", EVAL_SIMPLE_MATH),
- ("services/google-http.py", EVAL_SIMPLE_MATH),
- ("services/assemblyai.py", EVAL_SIMPLE_MATH),
- ("services/krisp-viva.py", EVAL_SIMPLE_MATH),
- ("services/rime.py", EVAL_SIMPLE_MATH),
- ("services/rime-http.py", EVAL_SIMPLE_MATH),
- ("services/nvidia.py", EVAL_SIMPLE_MATH),
- ("services/google-audio-in.py", EVAL_SIMPLE_MATH),
- ("services/fish.py", EVAL_SIMPLE_MATH),
- ("services/neuphonic.py", EVAL_SIMPLE_MATH),
- ("services/neuphonic-http.py", EVAL_SIMPLE_MATH),
- ("services/fal.py", EVAL_SIMPLE_MATH),
- ("services/minimax.py", EVAL_SIMPLE_MATH),
- ("services/sarvam.py", EVAL_SIMPLE_MATH),
- ("services/sarvam-http.py", EVAL_SIMPLE_MATH),
- ("services/soniox.py", EVAL_SIMPLE_MATH),
- ("services/inworld.py", EVAL_SIMPLE_MATH),
- ("services/inworld-http.py", EVAL_SIMPLE_MATH),
- ("services/asyncai.py", EVAL_SIMPLE_MATH),
- ("services/asyncai-http.py", EVAL_SIMPLE_MATH),
- ("services/aicoustics.py", EVAL_SIMPLE_MATH),
- ("services/hume.py", EVAL_SIMPLE_MATH),
- ("services/gradium.py", EVAL_SIMPLE_MATH),
- ("services/camb.py", EVAL_SIMPLE_MATH),
- ("services/piper.py", EVAL_SIMPLE_MATH),
- ("services/kokoro.py", EVAL_SIMPLE_MATH),
- ("services/resemble.py", EVAL_SIMPLE_MATH),
- ("services/smallest.py", EVAL_SIMPLE_MATH),
- ("services/openai-responses.py", EVAL_SIMPLE_MATH),
- ("services/openai-responses-http.py", EVAL_SIMPLE_MATH),
+ ("services/speech/cartesia.py", EVAL_SIMPLE_MATH),
+ ("services/speech/cartesia-http.py", EVAL_SIMPLE_MATH),
+ ("services/speech/speechmatics.py", EVAL_SIMPLE_MATH),
+ ("services/speech/speechmatics-vad.py", EVAL_SIMPLE_MATH),
+ ("services/speech/langchain.py", EVAL_SIMPLE_MATH),
+ ("services/speech/deepgram.py", EVAL_SIMPLE_MATH),
+ ("services/speech/deepgram-flux.py", EVAL_SIMPLE_MATH),
+ ("services/speech/deepgram-http.py", EVAL_SIMPLE_MATH),
+ ("services/speech/elevenlabs.py", EVAL_SIMPLE_MATH),
+ ("services/speech/elevenlabs-http.py", EVAL_SIMPLE_MATH),
+ ("services/speech/xai.py", EVAL_SIMPLE_MATH),
+ ("services/speech/azure.py", EVAL_SIMPLE_MATH),
+ ("services/speech/azure-http.py", EVAL_SIMPLE_MATH),
+ ("services/speech/openai.py", EVAL_SIMPLE_MATH),
+ ("services/speech/openai-http.py", EVAL_SIMPLE_MATH),
+ ("services/speech/gladia.py", EVAL_SIMPLE_MATH),
+ ("services/speech/gladia-vad.py", EVAL_SIMPLE_MATH),
+ ("services/speech/lmnt.py", EVAL_SIMPLE_MATH),
+ ("services/speech/groq.py", EVAL_SIMPLE_MATH),
+ ("services/speech/aws.py", EVAL_SIMPLE_MATH),
+ ("services/speech/aws-strands.py", EVAL_WEATHER),
+ ("services/speech/google-gemini-tts.py", EVAL_SIMPLE_MATH),
+ ("services/speech/google.py", EVAL_SIMPLE_MATH),
+ ("services/speech/google-http.py", EVAL_SIMPLE_MATH),
+ ("services/speech/assemblyai.py", EVAL_SIMPLE_MATH),
+ ("services/speech/krisp-viva.py", EVAL_SIMPLE_MATH),
+ ("services/speech/rime.py", EVAL_SIMPLE_MATH),
+ ("services/speech/rime-http.py", EVAL_SIMPLE_MATH),
+ ("services/speech/nvidia.py", EVAL_SIMPLE_MATH),
+ ("services/speech/google-audio-in.py", EVAL_SIMPLE_MATH),
+ ("services/speech/fish.py", EVAL_SIMPLE_MATH),
+ ("services/speech/neuphonic.py", EVAL_SIMPLE_MATH),
+ ("services/speech/neuphonic-http.py", EVAL_SIMPLE_MATH),
+ ("services/speech/fal.py", EVAL_SIMPLE_MATH),
+ ("services/speech/minimax.py", EVAL_SIMPLE_MATH),
+ ("services/speech/sarvam.py", EVAL_SIMPLE_MATH),
+ ("services/speech/sarvam-http.py", EVAL_SIMPLE_MATH),
+ ("services/speech/soniox.py", EVAL_SIMPLE_MATH),
+ ("services/speech/inworld.py", EVAL_SIMPLE_MATH),
+ ("services/speech/inworld-http.py", EVAL_SIMPLE_MATH),
+ ("services/speech/asyncai.py", EVAL_SIMPLE_MATH),
+ ("services/speech/asyncai-http.py", EVAL_SIMPLE_MATH),
+ ("services/speech/aicoustics.py", EVAL_SIMPLE_MATH),
+ ("services/speech/hume.py", EVAL_SIMPLE_MATH),
+ ("services/speech/gradium.py", EVAL_SIMPLE_MATH),
+ ("services/speech/camb.py", EVAL_SIMPLE_MATH),
+ ("services/speech/piper.py", EVAL_SIMPLE_MATH),
+ ("services/speech/kokoro.py", EVAL_SIMPLE_MATH),
+ ("services/speech/resemble.py", EVAL_SIMPLE_MATH),
+ ("services/speech/smallest.py", EVAL_SIMPLE_MATH),
+ ("services/speech/openai-responses.py", EVAL_SIMPLE_MATH),
+ ("services/speech/openai-responses-http.py", EVAL_SIMPLE_MATH),
# Needs a local XTTS docker instance running.
- # ("services/xtts.py", EVAL_SIMPLE_MATH),
+ # ("services/speech/xtts.py", EVAL_SIMPLE_MATH),
]
TESTS_VISION = [
@@ -169,44 +169,44 @@ TESTS_VISION = [
TESTS_FUNCTION_CALLING = [
("getting-started/07-function-calling.py", EVAL_WEATHER),
("getting-started/07-function-calling.py", EVAL_WEATHER_AND_RESTAURANT),
- ("function-calling/openai-responses.py", EVAL_WEATHER),
- ("function-calling/openai-responses.py", EVAL_WEATHER_AND_RESTAURANT),
- ("function-calling/openai-responses-http.py", EVAL_WEATHER),
- ("function-calling/openai-responses-http.py", EVAL_WEATHER_AND_RESTAURANT),
- ("function-calling/anthropic.py", EVAL_WEATHER),
- ("function-calling/anthropic.py", EVAL_WEATHER_AND_RESTAURANT),
- ("function-calling/openai.py", EVAL_WEATHER),
- ("function-calling/google.py", EVAL_WEATHER),
- ("function-calling/google.py", EVAL_WEATHER_AND_RESTAURANT),
- ("function-calling/groq.py", EVAL_WEATHER),
- ("function-calling/grok.py", EVAL_WEATHER),
- ("function-calling/azure.py", EVAL_WEATHER),
- ("function-calling/fireworks.py", EVAL_WEATHER),
- ("function-calling/nvidia.py", EVAL_WEATHER),
- ("function-calling/cerebras.py", EVAL_WEATHER),
- ("function-calling/openrouter.py", EVAL_WEATHER),
- ("function-calling/perplexity.py", EVAL_WEATHER),
- ("function-calling/google-vertex.py", EVAL_WEATHER),
- ("function-calling/qwen.py", EVAL_WEATHER),
- ("function-calling/aws.py", EVAL_WEATHER),
- ("function-calling/sambanova.py", EVAL_WEATHER),
- ("function-calling/aws.py", EVAL_WEATHER_AND_RESTAURANT),
- ("function-calling/nebius.py", EVAL_WEATHER),
- ("function-calling/mistral.py", EVAL_WEATHER),
- ("function-calling/sarvam.py", EVAL_WEATHER),
- ("function-calling/novita.py", EVAL_WEATHER),
+ ("services/function-calling/openai-responses.py", EVAL_WEATHER),
+ ("services/function-calling/openai-responses.py", EVAL_WEATHER_AND_RESTAURANT),
+ ("services/function-calling/openai-responses-http.py", EVAL_WEATHER),
+ ("services/function-calling/openai-responses-http.py", EVAL_WEATHER_AND_RESTAURANT),
+ ("services/function-calling/anthropic.py", EVAL_WEATHER),
+ ("services/function-calling/anthropic.py", EVAL_WEATHER_AND_RESTAURANT),
+ ("services/function-calling/openai.py", EVAL_WEATHER),
+ ("services/function-calling/google.py", EVAL_WEATHER),
+ ("services/function-calling/google.py", EVAL_WEATHER_AND_RESTAURANT),
+ ("services/function-calling/groq.py", EVAL_WEATHER),
+ ("services/function-calling/grok.py", EVAL_WEATHER),
+ ("services/function-calling/azure.py", EVAL_WEATHER),
+ ("services/function-calling/fireworks.py", EVAL_WEATHER),
+ ("services/function-calling/nvidia.py", EVAL_WEATHER),
+ ("services/function-calling/cerebras.py", EVAL_WEATHER),
+ ("services/function-calling/openrouter.py", EVAL_WEATHER),
+ ("services/function-calling/perplexity.py", EVAL_WEATHER),
+ ("services/function-calling/google-vertex.py", EVAL_WEATHER),
+ ("services/function-calling/qwen.py", EVAL_WEATHER),
+ ("services/function-calling/aws.py", EVAL_WEATHER),
+ ("services/function-calling/sambanova.py", EVAL_WEATHER),
+ ("services/function-calling/aws.py", EVAL_WEATHER_AND_RESTAURANT),
+ ("services/function-calling/nebius.py", EVAL_WEATHER),
+ ("services/function-calling/mistral.py", EVAL_WEATHER),
+ ("services/function-calling/sarvam.py", EVAL_WEATHER),
+ ("services/function-calling/novita.py", EVAL_WEATHER),
# Video
- ("function-calling/anthropic-video.py", EVAL_VISION_CAMERA),
- ("function-calling/aws-video.py", EVAL_VISION_CAMERA),
- ("function-calling/google-video.py", EVAL_VISION_CAMERA),
- ("function-calling/moondream-video.py", EVAL_VISION_CAMERA),
- ("function-calling/openai-video.py", EVAL_VISION_CAMERA),
- ("function-calling/openai-responses-video.py", EVAL_VISION_CAMERA),
- ("function-calling/openai-responses-video-http.py", EVAL_VISION_CAMERA),
+ ("services/function-calling/anthropic-video.py", EVAL_VISION_CAMERA),
+ ("services/function-calling/aws-video.py", EVAL_VISION_CAMERA),
+ ("services/function-calling/google-video.py", EVAL_VISION_CAMERA),
+ ("services/function-calling/moondream-video.py", EVAL_VISION_CAMERA),
+ ("services/function-calling/openai-video.py", EVAL_VISION_CAMERA),
+ ("services/function-calling/openai-responses-video.py", EVAL_VISION_CAMERA),
+ ("services/function-calling/openai-responses-video-http.py", EVAL_VISION_CAMERA),
# Currently not working.
- # ("function-calling/together.py", EVAL_WEATHER),
- # ("function-calling/deepseek.py", EVAL_WEATHER),
- # ("function-calling/gemini-openai-format.py", EVAL_WEATHER),
+ # ("services/function-calling/together.py", EVAL_WEATHER),
+ # ("services/function-calling/deepseek.py", EVAL_WEATHER),
+ # ("services/function-calling/gemini-openai-format.py", EVAL_WEATHER),
]
TESTS_FEATURES = [
From 47b41a0ff7284dbeef9fc5b4f24aa23c0aad187f Mon Sep 17 00:00:00 2001
From: Mark Backman
Date: Tue, 31 Mar 2026 15:12:06 -0400
Subject: [PATCH 12/19] Rename services/ to voice/ and function-calling/,
flatten to top level
Replace the nested services/speech/ and services/function-calling/ with
top-level voice/ and function-calling/ directories. Update eval script
paths and README to match.
---
examples/README.md | 9 +-
.../function-calling/anthropic-video.py | 0
.../function-calling/anthropic.py | 0
.../function-calling/aws-video.py | 0
.../{services => }/function-calling/aws.py | 0
.../{services => }/function-calling/azure.py | 0
.../function-calling/cerebras.py | 0
.../function-calling/deepseek.py | 0
.../{services => }/function-calling/direct.py | 0
.../function-calling/fireworks.py | 0
.../function-calling/gemini-openai-format.py | 0
.../function-calling/google-video.py | 0
.../{services => }/function-calling/google.py | 0
.../{services => }/function-calling/grok.py | 0
.../{services => }/function-calling/groq.py | 0
.../function-calling/mistral.py | 0
.../function-calling/moondream-video.py | 0
.../{services => }/function-calling/nebius.py | 0
.../{services => }/function-calling/novita.py | 0
.../{services => }/function-calling/nvidia.py | 0
.../{services => }/function-calling/ollama.py | 0
.../function-calling/openai-responses-http.py | 0
.../openai-responses-video-http.py | 0
.../openai-responses-video.py | 0
.../function-calling/openai-responses.py | 0
.../function-calling/openai-video.py | 0
.../{services => }/function-calling/openai.py | 0
.../function-calling/openrouter.py | 0
.../function-calling/perplexity.py | 0
.../{services => }/function-calling/qwen.py | 0
.../function-calling/sambanova.py | 0
.../{services => }/function-calling/sarvam.py | 0
.../function-calling/together.py | 0
.../function-calling/google-vertex-ai.py | 165 ----------------
.../{services/speech => voice}/aicoustics.py | 0
.../assemblyai-turn-detection.py | 0
.../{services/speech => voice}/assemblyai.py | 0
.../speech => voice}/asyncai-http.py | 0
.../{services/speech => voice}/asyncai.py | 0
.../{services/speech => voice}/aws-strands.py | 0
examples/{services/speech => voice}/aws.py | 0
.../{services/speech => voice}/azure-http.py | 0
examples/{services/speech => voice}/azure.py | 0
examples/{services/speech => voice}/camb.py | 0
.../speech => voice}/cartesia-http.py | 0
.../{services/speech => voice}/cartesia.py | 0
.../deepgram-flux-sagemaker.py | 0
.../speech => voice}/deepgram-flux.py | 0
.../speech => voice}/deepgram-http.py | 0
.../speech => voice}/deepgram-sagemaker.py | 0
.../speech => voice}/deepgram-vad.py | 0
.../{services/speech => voice}/deepgram.py | 0
.../speech => voice}/elevenlabs-http.py | 0
.../{services/speech => voice}/elevenlabs.py | 0
examples/{services/speech => voice}/fal.py | 0
examples/{services/speech => voice}/fish.py | 0
.../{services/speech => voice}/gladia-vad.py | 0
examples/{services/speech => voice}/gladia.py | 0
.../speech => voice}/google-audio-in.py | 0
.../speech => voice}/google-gemini-tts.py | 0
.../{services/speech => voice}/google-http.py | 0
.../speech => voice}/google-image.py | 0
examples/{services/speech => voice}/google.py | 0
.../{services/speech => voice}/gradium.py | 0
examples/{services/speech => voice}/groq.py | 0
examples/{services/speech => voice}/hume.py | 0
.../speech => voice}/inworld-http.py | 0
.../{services/speech => voice}/inworld.py | 0
examples/{services/speech => voice}/kokoro.py | 0
.../{services/speech => voice}/krisp-viva.py | 0
.../{services/speech => voice}/langchain.py | 0
examples/{services/speech => voice}/lmnt.py | 0
.../{services/speech => voice}/minimax.py | 0
.../speech => voice}/neuphonic-http.py | 0
.../{services/speech => voice}/neuphonic.py | 0
examples/{services/speech => voice}/nvidia.py | 0
.../{services/speech => voice}/openai-http.py | 0
.../speech => voice}/openai-responses-http.py | 0
.../speech => voice}/openai-responses.py | 0
examples/{services/speech => voice}/openai.py | 0
examples/{services/speech => voice}/piper.py | 0
.../{services/speech => voice}/resemble.py | 0
.../{services/speech => voice}/rime-http.py | 0
examples/{services/speech => voice}/rime.py | 0
.../{services/speech => voice}/sarvam-http.py | 0
examples/{services/speech => voice}/sarvam.py | 0
.../{services/speech => voice}/smallest.py | 0
examples/{services/speech => voice}/soniox.py | 0
.../speech => voice}/speechmatics-vad.py | 0
.../speech => voice}/speechmatics.py | 0
examples/{services/speech => voice}/xai.py | 0
examples/{services/speech => voice}/xtts.py | 0
scripts/evals/run-release-evals.py | 182 +++++++++---------
93 files changed, 96 insertions(+), 260 deletions(-)
rename examples/{services => }/function-calling/anthropic-video.py (100%)
rename examples/{services => }/function-calling/anthropic.py (100%)
rename examples/{services => }/function-calling/aws-video.py (100%)
rename examples/{services => }/function-calling/aws.py (100%)
rename examples/{services => }/function-calling/azure.py (100%)
rename examples/{services => }/function-calling/cerebras.py (100%)
rename examples/{services => }/function-calling/deepseek.py (100%)
rename examples/{services => }/function-calling/direct.py (100%)
rename examples/{services => }/function-calling/fireworks.py (100%)
rename examples/{services => }/function-calling/gemini-openai-format.py (100%)
rename examples/{services => }/function-calling/google-video.py (100%)
rename examples/{services => }/function-calling/google.py (100%)
rename examples/{services => }/function-calling/grok.py (100%)
rename examples/{services => }/function-calling/groq.py (100%)
rename examples/{services => }/function-calling/mistral.py (100%)
rename examples/{services => }/function-calling/moondream-video.py (100%)
rename examples/{services => }/function-calling/nebius.py (100%)
rename examples/{services => }/function-calling/novita.py (100%)
rename examples/{services => }/function-calling/nvidia.py (100%)
rename examples/{services => }/function-calling/ollama.py (100%)
rename examples/{services => }/function-calling/openai-responses-http.py (100%)
rename examples/{services => }/function-calling/openai-responses-video-http.py (100%)
rename examples/{services => }/function-calling/openai-responses-video.py (100%)
rename examples/{services => }/function-calling/openai-responses.py (100%)
rename examples/{services => }/function-calling/openai-video.py (100%)
rename examples/{services => }/function-calling/openai.py (100%)
rename examples/{services => }/function-calling/openrouter.py (100%)
rename examples/{services => }/function-calling/perplexity.py (100%)
rename examples/{services => }/function-calling/qwen.py (100%)
rename examples/{services => }/function-calling/sambanova.py (100%)
rename examples/{services => }/function-calling/sarvam.py (100%)
rename examples/{services => }/function-calling/together.py (100%)
delete mode 100644 examples/services/function-calling/google-vertex-ai.py
rename examples/{services/speech => voice}/aicoustics.py (100%)
rename examples/{services/speech => voice}/assemblyai-turn-detection.py (100%)
rename examples/{services/speech => voice}/assemblyai.py (100%)
rename examples/{services/speech => voice}/asyncai-http.py (100%)
rename examples/{services/speech => voice}/asyncai.py (100%)
rename examples/{services/speech => voice}/aws-strands.py (100%)
rename examples/{services/speech => voice}/aws.py (100%)
rename examples/{services/speech => voice}/azure-http.py (100%)
rename examples/{services/speech => voice}/azure.py (100%)
rename examples/{services/speech => voice}/camb.py (100%)
rename examples/{services/speech => voice}/cartesia-http.py (100%)
rename examples/{services/speech => voice}/cartesia.py (100%)
rename examples/{services/speech => voice}/deepgram-flux-sagemaker.py (100%)
rename examples/{services/speech => voice}/deepgram-flux.py (100%)
rename examples/{services/speech => voice}/deepgram-http.py (100%)
rename examples/{services/speech => voice}/deepgram-sagemaker.py (100%)
rename examples/{services/speech => voice}/deepgram-vad.py (100%)
rename examples/{services/speech => voice}/deepgram.py (100%)
rename examples/{services/speech => voice}/elevenlabs-http.py (100%)
rename examples/{services/speech => voice}/elevenlabs.py (100%)
rename examples/{services/speech => voice}/fal.py (100%)
rename examples/{services/speech => voice}/fish.py (100%)
rename examples/{services/speech => voice}/gladia-vad.py (100%)
rename examples/{services/speech => voice}/gladia.py (100%)
rename examples/{services/speech => voice}/google-audio-in.py (100%)
rename examples/{services/speech => voice}/google-gemini-tts.py (100%)
rename examples/{services/speech => voice}/google-http.py (100%)
rename examples/{services/speech => voice}/google-image.py (100%)
rename examples/{services/speech => voice}/google.py (100%)
rename examples/{services/speech => voice}/gradium.py (100%)
rename examples/{services/speech => voice}/groq.py (100%)
rename examples/{services/speech => voice}/hume.py (100%)
rename examples/{services/speech => voice}/inworld-http.py (100%)
rename examples/{services/speech => voice}/inworld.py (100%)
rename examples/{services/speech => voice}/kokoro.py (100%)
rename examples/{services/speech => voice}/krisp-viva.py (100%)
rename examples/{services/speech => voice}/langchain.py (100%)
rename examples/{services/speech => voice}/lmnt.py (100%)
rename examples/{services/speech => voice}/minimax.py (100%)
rename examples/{services/speech => voice}/neuphonic-http.py (100%)
rename examples/{services/speech => voice}/neuphonic.py (100%)
rename examples/{services/speech => voice}/nvidia.py (100%)
rename examples/{services/speech => voice}/openai-http.py (100%)
rename examples/{services/speech => voice}/openai-responses-http.py (100%)
rename examples/{services/speech => voice}/openai-responses.py (100%)
rename examples/{services/speech => voice}/openai.py (100%)
rename examples/{services/speech => voice}/piper.py (100%)
rename examples/{services/speech => voice}/resemble.py (100%)
rename examples/{services/speech => voice}/rime-http.py (100%)
rename examples/{services/speech => voice}/rime.py (100%)
rename examples/{services/speech => voice}/sarvam-http.py (100%)
rename examples/{services/speech => voice}/sarvam.py (100%)
rename examples/{services/speech => voice}/smallest.py (100%)
rename examples/{services/speech => voice}/soniox.py (100%)
rename examples/{services/speech => voice}/speechmatics-vad.py (100%)
rename examples/{services/speech => voice}/speechmatics.py (100%)
rename examples/{services/speech => voice}/xai.py (100%)
rename examples/{services/speech => voice}/xtts.py (100%)
diff --git a/examples/README.md b/examples/README.md
index 08dc58de5..5ec86002e 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -61,12 +61,13 @@ uv run getting-started/06-voice-agent.py -t twilio -x NGROK_HOST_NAME
Progressive introduction to Pipecat, from minimal TTS to a full voice agent with function calling.
-### [`services/`](./services/)
+### [`voice/`](./voice/)
-Service provider integration examples, organized into subfolders:
+Full STT + LLM + TTS voice agent pipelines showcasing different speech service providers (Deepgram, ElevenLabs, Cartesia, etc.)
-- **[`speech/`](./services/speech/)** — Full STT + LLM + TTS pipelines showcasing different speech service providers (Deepgram, ElevenLabs, Cartesia, etc.)
-- **[`function-calling/`](./services/function-calling/)** — Function calling with different LLM providers (OpenAI, Anthropic, Google, etc.)
+### [`function-calling/`](./function-calling/)
+
+Function calling with different LLM providers (OpenAI, Anthropic, Google, etc.)
### [`transcription/`](./transcription/)
diff --git a/examples/services/function-calling/anthropic-video.py b/examples/function-calling/anthropic-video.py
similarity index 100%
rename from examples/services/function-calling/anthropic-video.py
rename to examples/function-calling/anthropic-video.py
diff --git a/examples/services/function-calling/anthropic.py b/examples/function-calling/anthropic.py
similarity index 100%
rename from examples/services/function-calling/anthropic.py
rename to examples/function-calling/anthropic.py
diff --git a/examples/services/function-calling/aws-video.py b/examples/function-calling/aws-video.py
similarity index 100%
rename from examples/services/function-calling/aws-video.py
rename to examples/function-calling/aws-video.py
diff --git a/examples/services/function-calling/aws.py b/examples/function-calling/aws.py
similarity index 100%
rename from examples/services/function-calling/aws.py
rename to examples/function-calling/aws.py
diff --git a/examples/services/function-calling/azure.py b/examples/function-calling/azure.py
similarity index 100%
rename from examples/services/function-calling/azure.py
rename to examples/function-calling/azure.py
diff --git a/examples/services/function-calling/cerebras.py b/examples/function-calling/cerebras.py
similarity index 100%
rename from examples/services/function-calling/cerebras.py
rename to examples/function-calling/cerebras.py
diff --git a/examples/services/function-calling/deepseek.py b/examples/function-calling/deepseek.py
similarity index 100%
rename from examples/services/function-calling/deepseek.py
rename to examples/function-calling/deepseek.py
diff --git a/examples/services/function-calling/direct.py b/examples/function-calling/direct.py
similarity index 100%
rename from examples/services/function-calling/direct.py
rename to examples/function-calling/direct.py
diff --git a/examples/services/function-calling/fireworks.py b/examples/function-calling/fireworks.py
similarity index 100%
rename from examples/services/function-calling/fireworks.py
rename to examples/function-calling/fireworks.py
diff --git a/examples/services/function-calling/gemini-openai-format.py b/examples/function-calling/gemini-openai-format.py
similarity index 100%
rename from examples/services/function-calling/gemini-openai-format.py
rename to examples/function-calling/gemini-openai-format.py
diff --git a/examples/services/function-calling/google-video.py b/examples/function-calling/google-video.py
similarity index 100%
rename from examples/services/function-calling/google-video.py
rename to examples/function-calling/google-video.py
diff --git a/examples/services/function-calling/google.py b/examples/function-calling/google.py
similarity index 100%
rename from examples/services/function-calling/google.py
rename to examples/function-calling/google.py
diff --git a/examples/services/function-calling/grok.py b/examples/function-calling/grok.py
similarity index 100%
rename from examples/services/function-calling/grok.py
rename to examples/function-calling/grok.py
diff --git a/examples/services/function-calling/groq.py b/examples/function-calling/groq.py
similarity index 100%
rename from examples/services/function-calling/groq.py
rename to examples/function-calling/groq.py
diff --git a/examples/services/function-calling/mistral.py b/examples/function-calling/mistral.py
similarity index 100%
rename from examples/services/function-calling/mistral.py
rename to examples/function-calling/mistral.py
diff --git a/examples/services/function-calling/moondream-video.py b/examples/function-calling/moondream-video.py
similarity index 100%
rename from examples/services/function-calling/moondream-video.py
rename to examples/function-calling/moondream-video.py
diff --git a/examples/services/function-calling/nebius.py b/examples/function-calling/nebius.py
similarity index 100%
rename from examples/services/function-calling/nebius.py
rename to examples/function-calling/nebius.py
diff --git a/examples/services/function-calling/novita.py b/examples/function-calling/novita.py
similarity index 100%
rename from examples/services/function-calling/novita.py
rename to examples/function-calling/novita.py
diff --git a/examples/services/function-calling/nvidia.py b/examples/function-calling/nvidia.py
similarity index 100%
rename from examples/services/function-calling/nvidia.py
rename to examples/function-calling/nvidia.py
diff --git a/examples/services/function-calling/ollama.py b/examples/function-calling/ollama.py
similarity index 100%
rename from examples/services/function-calling/ollama.py
rename to examples/function-calling/ollama.py
diff --git a/examples/services/function-calling/openai-responses-http.py b/examples/function-calling/openai-responses-http.py
similarity index 100%
rename from examples/services/function-calling/openai-responses-http.py
rename to examples/function-calling/openai-responses-http.py
diff --git a/examples/services/function-calling/openai-responses-video-http.py b/examples/function-calling/openai-responses-video-http.py
similarity index 100%
rename from examples/services/function-calling/openai-responses-video-http.py
rename to examples/function-calling/openai-responses-video-http.py
diff --git a/examples/services/function-calling/openai-responses-video.py b/examples/function-calling/openai-responses-video.py
similarity index 100%
rename from examples/services/function-calling/openai-responses-video.py
rename to examples/function-calling/openai-responses-video.py
diff --git a/examples/services/function-calling/openai-responses.py b/examples/function-calling/openai-responses.py
similarity index 100%
rename from examples/services/function-calling/openai-responses.py
rename to examples/function-calling/openai-responses.py
diff --git a/examples/services/function-calling/openai-video.py b/examples/function-calling/openai-video.py
similarity index 100%
rename from examples/services/function-calling/openai-video.py
rename to examples/function-calling/openai-video.py
diff --git a/examples/services/function-calling/openai.py b/examples/function-calling/openai.py
similarity index 100%
rename from examples/services/function-calling/openai.py
rename to examples/function-calling/openai.py
diff --git a/examples/services/function-calling/openrouter.py b/examples/function-calling/openrouter.py
similarity index 100%
rename from examples/services/function-calling/openrouter.py
rename to examples/function-calling/openrouter.py
diff --git a/examples/services/function-calling/perplexity.py b/examples/function-calling/perplexity.py
similarity index 100%
rename from examples/services/function-calling/perplexity.py
rename to examples/function-calling/perplexity.py
diff --git a/examples/services/function-calling/qwen.py b/examples/function-calling/qwen.py
similarity index 100%
rename from examples/services/function-calling/qwen.py
rename to examples/function-calling/qwen.py
diff --git a/examples/services/function-calling/sambanova.py b/examples/function-calling/sambanova.py
similarity index 100%
rename from examples/services/function-calling/sambanova.py
rename to examples/function-calling/sambanova.py
diff --git a/examples/services/function-calling/sarvam.py b/examples/function-calling/sarvam.py
similarity index 100%
rename from examples/services/function-calling/sarvam.py
rename to examples/function-calling/sarvam.py
diff --git a/examples/services/function-calling/together.py b/examples/function-calling/together.py
similarity index 100%
rename from examples/services/function-calling/together.py
rename to examples/function-calling/together.py
diff --git a/examples/services/function-calling/google-vertex-ai.py b/examples/services/function-calling/google-vertex-ai.py
deleted file mode 100644
index 3bee2f1bb..000000000
--- a/examples/services/function-calling/google-vertex-ai.py
+++ /dev/null
@@ -1,165 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
-
-
-import os
-
-from dotenv import load_dotenv
-from loguru import logger
-
-from pipecat.adapters.schemas.function_schema import FunctionSchema
-from pipecat.adapters.schemas.tools_schema import ToolsSchema
-from pipecat.audio.vad.silero import SileroVADAnalyzer
-from pipecat.frames.frames import LLMRunFrame, TTSSpeakFrame
-from pipecat.pipeline.pipeline import Pipeline
-from pipecat.pipeline.runner import PipelineRunner
-from pipecat.pipeline.task import PipelineParams, PipelineTask
-from pipecat.processors.aggregators.llm_context import LLMContext
-from pipecat.processors.aggregators.llm_response_universal import (
- LLMContextAggregatorPair,
- LLMUserAggregatorParams,
-)
-from pipecat.runner.types import RunnerArguments
-from pipecat.runner.utils import create_transport
-from pipecat.services.deepgram.stt import DeepgramSTTService
-from pipecat.services.elevenlabs.tts import ElevenLabsTTSService
-from pipecat.services.google.vertex.llm import GoogleVertexLLMService
-from pipecat.services.llm_service import FunctionCallParams
-from pipecat.transports.base_transport import BaseTransport, TransportParams
-from pipecat.transports.daily.transport import DailyParams
-from pipecat.transports.websocket.fastapi import FastAPIWebsocketParams
-
-load_dotenv(override=True)
-
-
-async def fetch_weather_from_api(params: FunctionCallParams):
- await params.result_callback({"conditions": "nice", "temperature": "75"})
-
-
-# We use lambdas to defer transport parameter creation until the transport
-# type is selected at runtime.
-transport_params = {
- "daily": lambda: DailyParams(
- audio_in_enabled=True,
- audio_out_enabled=True,
- ),
- "twilio": lambda: FastAPIWebsocketParams(
- audio_in_enabled=True,
- audio_out_enabled=True,
- ),
- "webrtc": lambda: TransportParams(
- audio_in_enabled=True,
- audio_out_enabled=True,
- ),
-}
-
-
-async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
- logger.info(f"Starting bot")
-
- stt = DeepgramSTTService(api_key=os.getenv("DEEPGRAM_API_KEY"))
-
- tts = ElevenLabsTTSService(
- api_key=os.getenv("ELEVENLABS_API_KEY", ""),
- settings=ElevenLabsTTSService.Settings(
- voice=os.getenv("ELEVENLABS_VOICE_ID", ""),
- ),
- )
-
- llm = GoogleVertexLLMService(
- credentials=os.getenv("GOOGLE_VERTEX_TEST_CREDENTIALS"),
- project_id=os.getenv("GOOGLE_CLOUD_PROJECT_ID"),
- location=os.getenv("GOOGLE_CLOUD_LOCATION"),
- settings=GoogleVertexLLMService.Settings(
- system_instruction="You are a helpful assistant in a voice conversation. Your responses will be spoken aloud, so avoid emojis, bullet points, or other formatting that can't be spoken. Respond to what the user said in a creative, helpful, and brief way.",
- ),
- )
- # You can aslo register a function_name of None to get all functions
- # sent to the same callback with an additional function_name parameter.
- llm.register_function("get_current_weather", fetch_weather_from_api)
-
- @llm.event_handler("on_function_calls_started")
- async def on_function_calls_started(service, function_calls):
- await tts.queue_frame(TTSSpeakFrame("Let me check on that."))
-
- weather_function = FunctionSchema(
- name="get_current_weather",
- description="Get the current weather",
- properties={
- "location": {
- "type": "string",
- "description": "The city and state, e.g. San Francisco, CA",
- },
- "format": {
- "type": "string",
- "enum": ["celsius", "fahrenheit"],
- "description": "The temperature unit to use. Infer this from the user's location.",
- },
- },
- required=["location", "format"],
- )
- tools = ToolsSchema(standard_tools=[weather_function])
-
- messages = [
- {
- "role": "developer",
- "content": "Start a conversation with 'Hey there' to get the current weather.",
- },
- ]
-
- context = LLMContext(messages, tools)
- user_aggregator, assistant_aggregator = LLMContextAggregatorPair(
- context,
- user_params=LLMUserAggregatorParams(vad_analyzer=SileroVADAnalyzer()),
- )
-
- pipeline = Pipeline(
- [
- transport.input(),
- stt,
- user_aggregator,
- llm,
- tts,
- transport.output(),
- assistant_aggregator,
- ]
- )
-
- task = PipelineTask(
- pipeline,
- params=PipelineParams(
- enable_metrics=True,
- enable_usage_metrics=True,
- ),
- idle_timeout_secs=runner_args.pipeline_idle_timeout_secs,
- )
-
- @transport.event_handler("on_client_connected")
- async def on_client_connected(transport, client):
- logger.info(f"Client connected")
- # Kick off the conversation.
- await task.queue_frames([LLMRunFrame()])
-
- @transport.event_handler("on_client_disconnected")
- async def on_client_disconnected(transport, client):
- logger.info(f"Client disconnected")
- await task.cancel()
-
- runner = PipelineRunner(handle_sigint=runner_args.handle_sigint)
-
- await runner.run(task)
-
-
-async def bot(runner_args: RunnerArguments):
- """Main bot entry point compatible with Pipecat Cloud."""
- transport = await create_transport(runner_args, transport_params)
- await run_bot(transport, runner_args)
-
-
-if __name__ == "__main__":
- from pipecat.runner.run import main
-
- main()
diff --git a/examples/services/speech/aicoustics.py b/examples/voice/aicoustics.py
similarity index 100%
rename from examples/services/speech/aicoustics.py
rename to examples/voice/aicoustics.py
diff --git a/examples/services/speech/assemblyai-turn-detection.py b/examples/voice/assemblyai-turn-detection.py
similarity index 100%
rename from examples/services/speech/assemblyai-turn-detection.py
rename to examples/voice/assemblyai-turn-detection.py
diff --git a/examples/services/speech/assemblyai.py b/examples/voice/assemblyai.py
similarity index 100%
rename from examples/services/speech/assemblyai.py
rename to examples/voice/assemblyai.py
diff --git a/examples/services/speech/asyncai-http.py b/examples/voice/asyncai-http.py
similarity index 100%
rename from examples/services/speech/asyncai-http.py
rename to examples/voice/asyncai-http.py
diff --git a/examples/services/speech/asyncai.py b/examples/voice/asyncai.py
similarity index 100%
rename from examples/services/speech/asyncai.py
rename to examples/voice/asyncai.py
diff --git a/examples/services/speech/aws-strands.py b/examples/voice/aws-strands.py
similarity index 100%
rename from examples/services/speech/aws-strands.py
rename to examples/voice/aws-strands.py
diff --git a/examples/services/speech/aws.py b/examples/voice/aws.py
similarity index 100%
rename from examples/services/speech/aws.py
rename to examples/voice/aws.py
diff --git a/examples/services/speech/azure-http.py b/examples/voice/azure-http.py
similarity index 100%
rename from examples/services/speech/azure-http.py
rename to examples/voice/azure-http.py
diff --git a/examples/services/speech/azure.py b/examples/voice/azure.py
similarity index 100%
rename from examples/services/speech/azure.py
rename to examples/voice/azure.py
diff --git a/examples/services/speech/camb.py b/examples/voice/camb.py
similarity index 100%
rename from examples/services/speech/camb.py
rename to examples/voice/camb.py
diff --git a/examples/services/speech/cartesia-http.py b/examples/voice/cartesia-http.py
similarity index 100%
rename from examples/services/speech/cartesia-http.py
rename to examples/voice/cartesia-http.py
diff --git a/examples/services/speech/cartesia.py b/examples/voice/cartesia.py
similarity index 100%
rename from examples/services/speech/cartesia.py
rename to examples/voice/cartesia.py
diff --git a/examples/services/speech/deepgram-flux-sagemaker.py b/examples/voice/deepgram-flux-sagemaker.py
similarity index 100%
rename from examples/services/speech/deepgram-flux-sagemaker.py
rename to examples/voice/deepgram-flux-sagemaker.py
diff --git a/examples/services/speech/deepgram-flux.py b/examples/voice/deepgram-flux.py
similarity index 100%
rename from examples/services/speech/deepgram-flux.py
rename to examples/voice/deepgram-flux.py
diff --git a/examples/services/speech/deepgram-http.py b/examples/voice/deepgram-http.py
similarity index 100%
rename from examples/services/speech/deepgram-http.py
rename to examples/voice/deepgram-http.py
diff --git a/examples/services/speech/deepgram-sagemaker.py b/examples/voice/deepgram-sagemaker.py
similarity index 100%
rename from examples/services/speech/deepgram-sagemaker.py
rename to examples/voice/deepgram-sagemaker.py
diff --git a/examples/services/speech/deepgram-vad.py b/examples/voice/deepgram-vad.py
similarity index 100%
rename from examples/services/speech/deepgram-vad.py
rename to examples/voice/deepgram-vad.py
diff --git a/examples/services/speech/deepgram.py b/examples/voice/deepgram.py
similarity index 100%
rename from examples/services/speech/deepgram.py
rename to examples/voice/deepgram.py
diff --git a/examples/services/speech/elevenlabs-http.py b/examples/voice/elevenlabs-http.py
similarity index 100%
rename from examples/services/speech/elevenlabs-http.py
rename to examples/voice/elevenlabs-http.py
diff --git a/examples/services/speech/elevenlabs.py b/examples/voice/elevenlabs.py
similarity index 100%
rename from examples/services/speech/elevenlabs.py
rename to examples/voice/elevenlabs.py
diff --git a/examples/services/speech/fal.py b/examples/voice/fal.py
similarity index 100%
rename from examples/services/speech/fal.py
rename to examples/voice/fal.py
diff --git a/examples/services/speech/fish.py b/examples/voice/fish.py
similarity index 100%
rename from examples/services/speech/fish.py
rename to examples/voice/fish.py
diff --git a/examples/services/speech/gladia-vad.py b/examples/voice/gladia-vad.py
similarity index 100%
rename from examples/services/speech/gladia-vad.py
rename to examples/voice/gladia-vad.py
diff --git a/examples/services/speech/gladia.py b/examples/voice/gladia.py
similarity index 100%
rename from examples/services/speech/gladia.py
rename to examples/voice/gladia.py
diff --git a/examples/services/speech/google-audio-in.py b/examples/voice/google-audio-in.py
similarity index 100%
rename from examples/services/speech/google-audio-in.py
rename to examples/voice/google-audio-in.py
diff --git a/examples/services/speech/google-gemini-tts.py b/examples/voice/google-gemini-tts.py
similarity index 100%
rename from examples/services/speech/google-gemini-tts.py
rename to examples/voice/google-gemini-tts.py
diff --git a/examples/services/speech/google-http.py b/examples/voice/google-http.py
similarity index 100%
rename from examples/services/speech/google-http.py
rename to examples/voice/google-http.py
diff --git a/examples/services/speech/google-image.py b/examples/voice/google-image.py
similarity index 100%
rename from examples/services/speech/google-image.py
rename to examples/voice/google-image.py
diff --git a/examples/services/speech/google.py b/examples/voice/google.py
similarity index 100%
rename from examples/services/speech/google.py
rename to examples/voice/google.py
diff --git a/examples/services/speech/gradium.py b/examples/voice/gradium.py
similarity index 100%
rename from examples/services/speech/gradium.py
rename to examples/voice/gradium.py
diff --git a/examples/services/speech/groq.py b/examples/voice/groq.py
similarity index 100%
rename from examples/services/speech/groq.py
rename to examples/voice/groq.py
diff --git a/examples/services/speech/hume.py b/examples/voice/hume.py
similarity index 100%
rename from examples/services/speech/hume.py
rename to examples/voice/hume.py
diff --git a/examples/services/speech/inworld-http.py b/examples/voice/inworld-http.py
similarity index 100%
rename from examples/services/speech/inworld-http.py
rename to examples/voice/inworld-http.py
diff --git a/examples/services/speech/inworld.py b/examples/voice/inworld.py
similarity index 100%
rename from examples/services/speech/inworld.py
rename to examples/voice/inworld.py
diff --git a/examples/services/speech/kokoro.py b/examples/voice/kokoro.py
similarity index 100%
rename from examples/services/speech/kokoro.py
rename to examples/voice/kokoro.py
diff --git a/examples/services/speech/krisp-viva.py b/examples/voice/krisp-viva.py
similarity index 100%
rename from examples/services/speech/krisp-viva.py
rename to examples/voice/krisp-viva.py
diff --git a/examples/services/speech/langchain.py b/examples/voice/langchain.py
similarity index 100%
rename from examples/services/speech/langchain.py
rename to examples/voice/langchain.py
diff --git a/examples/services/speech/lmnt.py b/examples/voice/lmnt.py
similarity index 100%
rename from examples/services/speech/lmnt.py
rename to examples/voice/lmnt.py
diff --git a/examples/services/speech/minimax.py b/examples/voice/minimax.py
similarity index 100%
rename from examples/services/speech/minimax.py
rename to examples/voice/minimax.py
diff --git a/examples/services/speech/neuphonic-http.py b/examples/voice/neuphonic-http.py
similarity index 100%
rename from examples/services/speech/neuphonic-http.py
rename to examples/voice/neuphonic-http.py
diff --git a/examples/services/speech/neuphonic.py b/examples/voice/neuphonic.py
similarity index 100%
rename from examples/services/speech/neuphonic.py
rename to examples/voice/neuphonic.py
diff --git a/examples/services/speech/nvidia.py b/examples/voice/nvidia.py
similarity index 100%
rename from examples/services/speech/nvidia.py
rename to examples/voice/nvidia.py
diff --git a/examples/services/speech/openai-http.py b/examples/voice/openai-http.py
similarity index 100%
rename from examples/services/speech/openai-http.py
rename to examples/voice/openai-http.py
diff --git a/examples/services/speech/openai-responses-http.py b/examples/voice/openai-responses-http.py
similarity index 100%
rename from examples/services/speech/openai-responses-http.py
rename to examples/voice/openai-responses-http.py
diff --git a/examples/services/speech/openai-responses.py b/examples/voice/openai-responses.py
similarity index 100%
rename from examples/services/speech/openai-responses.py
rename to examples/voice/openai-responses.py
diff --git a/examples/services/speech/openai.py b/examples/voice/openai.py
similarity index 100%
rename from examples/services/speech/openai.py
rename to examples/voice/openai.py
diff --git a/examples/services/speech/piper.py b/examples/voice/piper.py
similarity index 100%
rename from examples/services/speech/piper.py
rename to examples/voice/piper.py
diff --git a/examples/services/speech/resemble.py b/examples/voice/resemble.py
similarity index 100%
rename from examples/services/speech/resemble.py
rename to examples/voice/resemble.py
diff --git a/examples/services/speech/rime-http.py b/examples/voice/rime-http.py
similarity index 100%
rename from examples/services/speech/rime-http.py
rename to examples/voice/rime-http.py
diff --git a/examples/services/speech/rime.py b/examples/voice/rime.py
similarity index 100%
rename from examples/services/speech/rime.py
rename to examples/voice/rime.py
diff --git a/examples/services/speech/sarvam-http.py b/examples/voice/sarvam-http.py
similarity index 100%
rename from examples/services/speech/sarvam-http.py
rename to examples/voice/sarvam-http.py
diff --git a/examples/services/speech/sarvam.py b/examples/voice/sarvam.py
similarity index 100%
rename from examples/services/speech/sarvam.py
rename to examples/voice/sarvam.py
diff --git a/examples/services/speech/smallest.py b/examples/voice/smallest.py
similarity index 100%
rename from examples/services/speech/smallest.py
rename to examples/voice/smallest.py
diff --git a/examples/services/speech/soniox.py b/examples/voice/soniox.py
similarity index 100%
rename from examples/services/speech/soniox.py
rename to examples/voice/soniox.py
diff --git a/examples/services/speech/speechmatics-vad.py b/examples/voice/speechmatics-vad.py
similarity index 100%
rename from examples/services/speech/speechmatics-vad.py
rename to examples/voice/speechmatics-vad.py
diff --git a/examples/services/speech/speechmatics.py b/examples/voice/speechmatics.py
similarity index 100%
rename from examples/services/speech/speechmatics.py
rename to examples/voice/speechmatics.py
diff --git a/examples/services/speech/xai.py b/examples/voice/xai.py
similarity index 100%
rename from examples/services/speech/xai.py
rename to examples/voice/xai.py
diff --git a/examples/services/speech/xtts.py b/examples/voice/xtts.py
similarity index 100%
rename from examples/services/speech/xtts.py
rename to examples/voice/xtts.py
diff --git a/scripts/evals/run-release-evals.py b/scripts/evals/run-release-evals.py
index 3c540ff87..be3bd1295 100644
--- a/scripts/evals/run-release-evals.py
+++ b/scripts/evals/run-release-evals.py
@@ -96,61 +96,61 @@ EVAL_COMPLETE_TURN = EvalConfig(
)
-TESTS_SPEECH = [
- ("services/speech/cartesia.py", EVAL_SIMPLE_MATH),
- ("services/speech/cartesia-http.py", EVAL_SIMPLE_MATH),
- ("services/speech/speechmatics.py", EVAL_SIMPLE_MATH),
- ("services/speech/speechmatics-vad.py", EVAL_SIMPLE_MATH),
- ("services/speech/langchain.py", EVAL_SIMPLE_MATH),
- ("services/speech/deepgram.py", EVAL_SIMPLE_MATH),
- ("services/speech/deepgram-flux.py", EVAL_SIMPLE_MATH),
- ("services/speech/deepgram-http.py", EVAL_SIMPLE_MATH),
- ("services/speech/elevenlabs.py", EVAL_SIMPLE_MATH),
- ("services/speech/elevenlabs-http.py", EVAL_SIMPLE_MATH),
- ("services/speech/xai.py", EVAL_SIMPLE_MATH),
- ("services/speech/azure.py", EVAL_SIMPLE_MATH),
- ("services/speech/azure-http.py", EVAL_SIMPLE_MATH),
- ("services/speech/openai.py", EVAL_SIMPLE_MATH),
- ("services/speech/openai-http.py", EVAL_SIMPLE_MATH),
- ("services/speech/gladia.py", EVAL_SIMPLE_MATH),
- ("services/speech/gladia-vad.py", EVAL_SIMPLE_MATH),
- ("services/speech/lmnt.py", EVAL_SIMPLE_MATH),
- ("services/speech/groq.py", EVAL_SIMPLE_MATH),
- ("services/speech/aws.py", EVAL_SIMPLE_MATH),
- ("services/speech/aws-strands.py", EVAL_WEATHER),
- ("services/speech/google-gemini-tts.py", EVAL_SIMPLE_MATH),
- ("services/speech/google.py", EVAL_SIMPLE_MATH),
- ("services/speech/google-http.py", EVAL_SIMPLE_MATH),
- ("services/speech/assemblyai.py", EVAL_SIMPLE_MATH),
- ("services/speech/krisp-viva.py", EVAL_SIMPLE_MATH),
- ("services/speech/rime.py", EVAL_SIMPLE_MATH),
- ("services/speech/rime-http.py", EVAL_SIMPLE_MATH),
- ("services/speech/nvidia.py", EVAL_SIMPLE_MATH),
- ("services/speech/google-audio-in.py", EVAL_SIMPLE_MATH),
- ("services/speech/fish.py", EVAL_SIMPLE_MATH),
- ("services/speech/neuphonic.py", EVAL_SIMPLE_MATH),
- ("services/speech/neuphonic-http.py", EVAL_SIMPLE_MATH),
- ("services/speech/fal.py", EVAL_SIMPLE_MATH),
- ("services/speech/minimax.py", EVAL_SIMPLE_MATH),
- ("services/speech/sarvam.py", EVAL_SIMPLE_MATH),
- ("services/speech/sarvam-http.py", EVAL_SIMPLE_MATH),
- ("services/speech/soniox.py", EVAL_SIMPLE_MATH),
- ("services/speech/inworld.py", EVAL_SIMPLE_MATH),
- ("services/speech/inworld-http.py", EVAL_SIMPLE_MATH),
- ("services/speech/asyncai.py", EVAL_SIMPLE_MATH),
- ("services/speech/asyncai-http.py", EVAL_SIMPLE_MATH),
- ("services/speech/aicoustics.py", EVAL_SIMPLE_MATH),
- ("services/speech/hume.py", EVAL_SIMPLE_MATH),
- ("services/speech/gradium.py", EVAL_SIMPLE_MATH),
- ("services/speech/camb.py", EVAL_SIMPLE_MATH),
- ("services/speech/piper.py", EVAL_SIMPLE_MATH),
- ("services/speech/kokoro.py", EVAL_SIMPLE_MATH),
- ("services/speech/resemble.py", EVAL_SIMPLE_MATH),
- ("services/speech/smallest.py", EVAL_SIMPLE_MATH),
- ("services/speech/openai-responses.py", EVAL_SIMPLE_MATH),
- ("services/speech/openai-responses-http.py", EVAL_SIMPLE_MATH),
+TESTS_VOICE = [
+ ("voice/cartesia.py", EVAL_SIMPLE_MATH),
+ ("voice/cartesia-http.py", EVAL_SIMPLE_MATH),
+ ("voice/speechmatics.py", EVAL_SIMPLE_MATH),
+ ("voice/speechmatics-vad.py", EVAL_SIMPLE_MATH),
+ ("voice/langchain.py", EVAL_SIMPLE_MATH),
+ ("voice/deepgram.py", EVAL_SIMPLE_MATH),
+ ("voice/deepgram-flux.py", EVAL_SIMPLE_MATH),
+ ("voice/deepgram-http.py", EVAL_SIMPLE_MATH),
+ ("voice/elevenlabs.py", EVAL_SIMPLE_MATH),
+ ("voice/elevenlabs-http.py", EVAL_SIMPLE_MATH),
+ ("voice/xai.py", EVAL_SIMPLE_MATH),
+ ("voice/azure.py", EVAL_SIMPLE_MATH),
+ ("voice/azure-http.py", EVAL_SIMPLE_MATH),
+ ("voice/openai.py", EVAL_SIMPLE_MATH),
+ ("voice/openai-http.py", EVAL_SIMPLE_MATH),
+ ("voice/gladia.py", EVAL_SIMPLE_MATH),
+ ("voice/gladia-vad.py", EVAL_SIMPLE_MATH),
+ ("voice/lmnt.py", EVAL_SIMPLE_MATH),
+ ("voice/groq.py", EVAL_SIMPLE_MATH),
+ ("voice/aws.py", EVAL_SIMPLE_MATH),
+ ("voice/aws-strands.py", EVAL_WEATHER),
+ ("voice/google-gemini-tts.py", EVAL_SIMPLE_MATH),
+ ("voice/google.py", EVAL_SIMPLE_MATH),
+ ("voice/google-http.py", EVAL_SIMPLE_MATH),
+ ("voice/assemblyai.py", EVAL_SIMPLE_MATH),
+ ("voice/krisp-viva.py", EVAL_SIMPLE_MATH),
+ ("voice/rime.py", EVAL_SIMPLE_MATH),
+ ("voice/rime-http.py", EVAL_SIMPLE_MATH),
+ ("voice/nvidia.py", EVAL_SIMPLE_MATH),
+ ("voice/google-audio-in.py", EVAL_SIMPLE_MATH),
+ ("voice/fish.py", EVAL_SIMPLE_MATH),
+ ("voice/neuphonic.py", EVAL_SIMPLE_MATH),
+ ("voice/neuphonic-http.py", EVAL_SIMPLE_MATH),
+ ("voice/fal.py", EVAL_SIMPLE_MATH),
+ ("voice/minimax.py", EVAL_SIMPLE_MATH),
+ ("voice/sarvam.py", EVAL_SIMPLE_MATH),
+ ("voice/sarvam-http.py", EVAL_SIMPLE_MATH),
+ ("voice/soniox.py", EVAL_SIMPLE_MATH),
+ ("voice/inworld.py", EVAL_SIMPLE_MATH),
+ ("voice/inworld-http.py", EVAL_SIMPLE_MATH),
+ ("voice/asyncai.py", EVAL_SIMPLE_MATH),
+ ("voice/asyncai-http.py", EVAL_SIMPLE_MATH),
+ ("voice/aicoustics.py", EVAL_SIMPLE_MATH),
+ ("voice/hume.py", EVAL_SIMPLE_MATH),
+ ("voice/gradium.py", EVAL_SIMPLE_MATH),
+ ("voice/camb.py", EVAL_SIMPLE_MATH),
+ ("voice/piper.py", EVAL_SIMPLE_MATH),
+ ("voice/kokoro.py", EVAL_SIMPLE_MATH),
+ ("voice/resemble.py", EVAL_SIMPLE_MATH),
+ ("voice/smallest.py", EVAL_SIMPLE_MATH),
+ ("voice/openai-responses.py", EVAL_SIMPLE_MATH),
+ ("voice/openai-responses-http.py", EVAL_SIMPLE_MATH),
# Needs a local XTTS docker instance running.
- # ("services/speech/xtts.py", EVAL_SIMPLE_MATH),
+ # ("voice/xtts.py", EVAL_SIMPLE_MATH),
]
TESTS_VISION = [
@@ -169,44 +169,44 @@ TESTS_VISION = [
TESTS_FUNCTION_CALLING = [
("getting-started/07-function-calling.py", EVAL_WEATHER),
("getting-started/07-function-calling.py", EVAL_WEATHER_AND_RESTAURANT),
- ("services/function-calling/openai-responses.py", EVAL_WEATHER),
- ("services/function-calling/openai-responses.py", EVAL_WEATHER_AND_RESTAURANT),
- ("services/function-calling/openai-responses-http.py", EVAL_WEATHER),
- ("services/function-calling/openai-responses-http.py", EVAL_WEATHER_AND_RESTAURANT),
- ("services/function-calling/anthropic.py", EVAL_WEATHER),
- ("services/function-calling/anthropic.py", EVAL_WEATHER_AND_RESTAURANT),
- ("services/function-calling/openai.py", EVAL_WEATHER),
- ("services/function-calling/google.py", EVAL_WEATHER),
- ("services/function-calling/google.py", EVAL_WEATHER_AND_RESTAURANT),
- ("services/function-calling/groq.py", EVAL_WEATHER),
- ("services/function-calling/grok.py", EVAL_WEATHER),
- ("services/function-calling/azure.py", EVAL_WEATHER),
- ("services/function-calling/fireworks.py", EVAL_WEATHER),
- ("services/function-calling/nvidia.py", EVAL_WEATHER),
- ("services/function-calling/cerebras.py", EVAL_WEATHER),
- ("services/function-calling/openrouter.py", EVAL_WEATHER),
- ("services/function-calling/perplexity.py", EVAL_WEATHER),
- ("services/function-calling/google-vertex.py", EVAL_WEATHER),
- ("services/function-calling/qwen.py", EVAL_WEATHER),
- ("services/function-calling/aws.py", EVAL_WEATHER),
- ("services/function-calling/sambanova.py", EVAL_WEATHER),
- ("services/function-calling/aws.py", EVAL_WEATHER_AND_RESTAURANT),
- ("services/function-calling/nebius.py", EVAL_WEATHER),
- ("services/function-calling/mistral.py", EVAL_WEATHER),
- ("services/function-calling/sarvam.py", EVAL_WEATHER),
- ("services/function-calling/novita.py", EVAL_WEATHER),
+ ("function-calling/openai-responses.py", EVAL_WEATHER),
+ ("function-calling/openai-responses.py", EVAL_WEATHER_AND_RESTAURANT),
+ ("function-calling/openai-responses-http.py", EVAL_WEATHER),
+ ("function-calling/openai-responses-http.py", EVAL_WEATHER_AND_RESTAURANT),
+ ("function-calling/anthropic.py", EVAL_WEATHER),
+ ("function-calling/anthropic.py", EVAL_WEATHER_AND_RESTAURANT),
+ ("function-calling/openai.py", EVAL_WEATHER),
+ ("function-calling/google.py", EVAL_WEATHER),
+ ("function-calling/google.py", EVAL_WEATHER_AND_RESTAURANT),
+ ("function-calling/groq.py", EVAL_WEATHER),
+ ("function-calling/grok.py", EVAL_WEATHER),
+ ("function-calling/azure.py", EVAL_WEATHER),
+ ("function-calling/fireworks.py", EVAL_WEATHER),
+ ("function-calling/nvidia.py", EVAL_WEATHER),
+ ("function-calling/cerebras.py", EVAL_WEATHER),
+ ("function-calling/openrouter.py", EVAL_WEATHER),
+ ("function-calling/perplexity.py", EVAL_WEATHER),
+ ("function-calling/google-vertex.py", EVAL_WEATHER),
+ ("function-calling/qwen.py", EVAL_WEATHER),
+ ("function-calling/aws.py", EVAL_WEATHER),
+ ("function-calling/sambanova.py", EVAL_WEATHER),
+ ("function-calling/aws.py", EVAL_WEATHER_AND_RESTAURANT),
+ ("function-calling/nebius.py", EVAL_WEATHER),
+ ("function-calling/mistral.py", EVAL_WEATHER),
+ ("function-calling/sarvam.py", EVAL_WEATHER),
+ ("function-calling/novita.py", EVAL_WEATHER),
# Video
- ("services/function-calling/anthropic-video.py", EVAL_VISION_CAMERA),
- ("services/function-calling/aws-video.py", EVAL_VISION_CAMERA),
- ("services/function-calling/google-video.py", EVAL_VISION_CAMERA),
- ("services/function-calling/moondream-video.py", EVAL_VISION_CAMERA),
- ("services/function-calling/openai-video.py", EVAL_VISION_CAMERA),
- ("services/function-calling/openai-responses-video.py", EVAL_VISION_CAMERA),
- ("services/function-calling/openai-responses-video-http.py", EVAL_VISION_CAMERA),
+ ("function-calling/anthropic-video.py", EVAL_VISION_CAMERA),
+ ("function-calling/aws-video.py", EVAL_VISION_CAMERA),
+ ("function-calling/google-video.py", EVAL_VISION_CAMERA),
+ ("function-calling/moondream-video.py", EVAL_VISION_CAMERA),
+ ("function-calling/openai-video.py", EVAL_VISION_CAMERA),
+ ("function-calling/openai-responses-video.py", EVAL_VISION_CAMERA),
+ ("function-calling/openai-responses-video-http.py", EVAL_VISION_CAMERA),
# Currently not working.
- # ("services/function-calling/together.py", EVAL_WEATHER),
- # ("services/function-calling/deepseek.py", EVAL_WEATHER),
- # ("services/function-calling/gemini-openai-format.py", EVAL_WEATHER),
+ # ("function-calling/together.py", EVAL_WEATHER),
+ # ("function-calling/deepseek.py", EVAL_WEATHER),
+ # ("function-calling/gemini-openai-format.py", EVAL_WEATHER),
]
TESTS_FEATURES = [
@@ -257,7 +257,7 @@ TESTS_THINKING_AND_MCP = [
]
TESTS = [
- *TESTS_SPEECH,
+ *TESTS_VOICE,
*TESTS_VISION,
*TESTS_FUNCTION_CALLING,
*TESTS_FEATURES,
From 27cb078716ad19f2ccd619dae61ab1968401b9d2 Mon Sep 17 00:00:00 2001
From: Mark Backman
Date: Tue, 31 Mar 2026 15:25:52 -0400
Subject: [PATCH 13/19] Add missing google-vertex.py file
---
examples/function-calling/google-vertex.py | 165 +++++++++++++++++++++
1 file changed, 165 insertions(+)
create mode 100644 examples/function-calling/google-vertex.py
diff --git a/examples/function-calling/google-vertex.py b/examples/function-calling/google-vertex.py
new file mode 100644
index 000000000..3bee2f1bb
--- /dev/null
+++ b/examples/function-calling/google-vertex.py
@@ -0,0 +1,165 @@
+#
+# Copyright (c) 2024-2026, Daily
+#
+# SPDX-License-Identifier: BSD 2-Clause License
+#
+
+
+import os
+
+from dotenv import load_dotenv
+from loguru import logger
+
+from pipecat.adapters.schemas.function_schema import FunctionSchema
+from pipecat.adapters.schemas.tools_schema import ToolsSchema
+from pipecat.audio.vad.silero import SileroVADAnalyzer
+from pipecat.frames.frames import LLMRunFrame, TTSSpeakFrame
+from pipecat.pipeline.pipeline import Pipeline
+from pipecat.pipeline.runner import PipelineRunner
+from pipecat.pipeline.task import PipelineParams, PipelineTask
+from pipecat.processors.aggregators.llm_context import LLMContext
+from pipecat.processors.aggregators.llm_response_universal import (
+ LLMContextAggregatorPair,
+ LLMUserAggregatorParams,
+)
+from pipecat.runner.types import RunnerArguments
+from pipecat.runner.utils import create_transport
+from pipecat.services.deepgram.stt import DeepgramSTTService
+from pipecat.services.elevenlabs.tts import ElevenLabsTTSService
+from pipecat.services.google.vertex.llm import GoogleVertexLLMService
+from pipecat.services.llm_service import FunctionCallParams
+from pipecat.transports.base_transport import BaseTransport, TransportParams
+from pipecat.transports.daily.transport import DailyParams
+from pipecat.transports.websocket.fastapi import FastAPIWebsocketParams
+
+load_dotenv(override=True)
+
+
+async def fetch_weather_from_api(params: FunctionCallParams):
+ await params.result_callback({"conditions": "nice", "temperature": "75"})
+
+
+# We use lambdas to defer transport parameter creation until the transport
+# type is selected at runtime.
+transport_params = {
+ "daily": lambda: DailyParams(
+ audio_in_enabled=True,
+ audio_out_enabled=True,
+ ),
+ "twilio": lambda: FastAPIWebsocketParams(
+ audio_in_enabled=True,
+ audio_out_enabled=True,
+ ),
+ "webrtc": lambda: TransportParams(
+ audio_in_enabled=True,
+ audio_out_enabled=True,
+ ),
+}
+
+
+async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
+ logger.info(f"Starting bot")
+
+ stt = DeepgramSTTService(api_key=os.getenv("DEEPGRAM_API_KEY"))
+
+ tts = ElevenLabsTTSService(
+ api_key=os.getenv("ELEVENLABS_API_KEY", ""),
+ settings=ElevenLabsTTSService.Settings(
+ voice=os.getenv("ELEVENLABS_VOICE_ID", ""),
+ ),
+ )
+
+ llm = GoogleVertexLLMService(
+ credentials=os.getenv("GOOGLE_VERTEX_TEST_CREDENTIALS"),
+ project_id=os.getenv("GOOGLE_CLOUD_PROJECT_ID"),
+ location=os.getenv("GOOGLE_CLOUD_LOCATION"),
+ settings=GoogleVertexLLMService.Settings(
+ system_instruction="You are a helpful assistant in a voice conversation. Your responses will be spoken aloud, so avoid emojis, bullet points, or other formatting that can't be spoken. Respond to what the user said in a creative, helpful, and brief way.",
+ ),
+ )
+ # You can aslo register a function_name of None to get all functions
+ # sent to the same callback with an additional function_name parameter.
+ llm.register_function("get_current_weather", fetch_weather_from_api)
+
+ @llm.event_handler("on_function_calls_started")
+ async def on_function_calls_started(service, function_calls):
+ await tts.queue_frame(TTSSpeakFrame("Let me check on that."))
+
+ weather_function = FunctionSchema(
+ name="get_current_weather",
+ description="Get the current weather",
+ properties={
+ "location": {
+ "type": "string",
+ "description": "The city and state, e.g. San Francisco, CA",
+ },
+ "format": {
+ "type": "string",
+ "enum": ["celsius", "fahrenheit"],
+ "description": "The temperature unit to use. Infer this from the user's location.",
+ },
+ },
+ required=["location", "format"],
+ )
+ tools = ToolsSchema(standard_tools=[weather_function])
+
+ messages = [
+ {
+ "role": "developer",
+ "content": "Start a conversation with 'Hey there' to get the current weather.",
+ },
+ ]
+
+ context = LLMContext(messages, tools)
+ user_aggregator, assistant_aggregator = LLMContextAggregatorPair(
+ context,
+ user_params=LLMUserAggregatorParams(vad_analyzer=SileroVADAnalyzer()),
+ )
+
+ pipeline = Pipeline(
+ [
+ transport.input(),
+ stt,
+ user_aggregator,
+ llm,
+ tts,
+ transport.output(),
+ assistant_aggregator,
+ ]
+ )
+
+ task = PipelineTask(
+ pipeline,
+ params=PipelineParams(
+ enable_metrics=True,
+ enable_usage_metrics=True,
+ ),
+ idle_timeout_secs=runner_args.pipeline_idle_timeout_secs,
+ )
+
+ @transport.event_handler("on_client_connected")
+ async def on_client_connected(transport, client):
+ logger.info(f"Client connected")
+ # Kick off the conversation.
+ await task.queue_frames([LLMRunFrame()])
+
+ @transport.event_handler("on_client_disconnected")
+ async def on_client_disconnected(transport, client):
+ logger.info(f"Client disconnected")
+ await task.cancel()
+
+ runner = PipelineRunner(handle_sigint=runner_args.handle_sigint)
+
+ await runner.run(task)
+
+
+async def bot(runner_args: RunnerArguments):
+ """Main bot entry point compatible with Pipecat Cloud."""
+ transport = await create_transport(runner_args, transport_params)
+ await run_bot(transport, runner_args)
+
+
+if __name__ == "__main__":
+ from pipecat.runner.run import main
+
+ main()
From 7501effad54e0bded902a9f60117d01296562b72 Mon Sep 17 00:00:00 2001
From: Mark Backman
Date: Mon, 30 Mar 2026 20:48:02 -0400
Subject: [PATCH 14/19] Remove deprecated service module shims and old
implementations
Delete deprecated import shims that only re-export from new locations:
- services/ai_services.py
- services/gemini_multimodal_live/
- services/aws_nova_sonic/
- services/openai_realtime/
- services/deepgram/{stt,tts}_sagemaker.py
- services/google/{llm_openai,llm_vertex,google}.py
- services/google/gemini_live/llm_vertex.py
- services/riva/
- services/nim/
Remove deprecated implementations replaced by newer services:
- services/openai_realtime_beta/ (use openai.realtime)
- services/google/openai/ (use google.llm)
Also removes associated examples and tests for deleted services.
---
.../function-calling/gemini-openai-format.py | 162 ---
.../openai-realtime-beta.py | 267 -----
examples/realtime/azure-beta.py | 214 ----
examples/realtime/openai-beta-text.py | 215 ----
examples/realtime/openai-beta.py | 219 ----
src/pipecat/services/ai_services.py | 33 -
.../services/aws_nova_sonic/__init__.py | 24 -
src/pipecat/services/aws_nova_sonic/aws.py | 25 -
.../services/aws_nova_sonic/context.py | 21 -
src/pipecat/services/aws_nova_sonic/frames.py | 21 -
.../services/deepgram/stt_sagemaker.py | 18 -
.../services/deepgram/tts_sagemaker.py | 18 -
.../gemini_multimodal_live/__init__.py | 7 -
.../services/gemini_multimodal_live/events.py | 44 -
.../gemini_multimodal_live/file_api.py | 39 -
.../services/gemini_multimodal_live/gemini.py | 57 -
src/pipecat/services/google/__init__.py | 3 +-
.../services/google/gemini_live/llm_vertex.py | 18 -
src/pipecat/services/google/google.py | 24 -
src/pipecat/services/google/llm_openai.py | 18 -
src/pipecat/services/google/llm_vertex.py | 18 -
.../services/google/openai/__init__.py | 5 -
src/pipecat/services/google/openai/llm.py | 217 ----
src/pipecat/services/grok/llm.py | 2 +-
src/pipecat/services/grok/realtime/events.py | 2 +-
src/pipecat/services/grok/realtime/llm.py | 2 +-
src/pipecat/services/nim/__init__.py | 13 -
src/pipecat/services/nim/llm.py | 30 -
.../services/openai_realtime/__init__.py | 37 -
src/pipecat/services/openai_realtime/azure.py | 21 -
.../services/openai_realtime/context.py | 18 -
.../services/openai_realtime/events.py | 21 -
.../services/openai_realtime/frames.py | 21 -
.../services/openai_realtime_beta/__init__.py | 19 -
.../services/openai_realtime_beta/azure.py | 94 --
.../services/openai_realtime_beta/context.py | 272 -----
.../services/openai_realtime_beta/events.py | 978 ------------------
.../services/openai_realtime_beta/frames.py | 37 -
.../services/openai_realtime_beta/openai.py | 858 ---------------
src/pipecat/services/riva/__init__.py | 14 -
src/pipecat/services/riva/stt.py | 35 -
src/pipecat/services/riva/tts.py | 33 -
.../utils/tracing/service_attributes.py | 1 -
tests/test_google_llm_openai.py | 81 --
tests/test_settings.py | 2 +-
45 files changed, 5 insertions(+), 4273 deletions(-)
delete mode 100644 examples/function-calling/gemini-openai-format.py
delete mode 100644 examples/persistent-context/openai-realtime-beta.py
delete mode 100644 examples/realtime/azure-beta.py
delete mode 100644 examples/realtime/openai-beta-text.py
delete mode 100644 examples/realtime/openai-beta.py
delete mode 100644 src/pipecat/services/ai_services.py
delete mode 100644 src/pipecat/services/aws_nova_sonic/__init__.py
delete mode 100644 src/pipecat/services/aws_nova_sonic/aws.py
delete mode 100644 src/pipecat/services/aws_nova_sonic/context.py
delete mode 100644 src/pipecat/services/aws_nova_sonic/frames.py
delete mode 100644 src/pipecat/services/deepgram/stt_sagemaker.py
delete mode 100644 src/pipecat/services/deepgram/tts_sagemaker.py
delete mode 100644 src/pipecat/services/gemini_multimodal_live/__init__.py
delete mode 100644 src/pipecat/services/gemini_multimodal_live/events.py
delete mode 100644 src/pipecat/services/gemini_multimodal_live/file_api.py
delete mode 100644 src/pipecat/services/gemini_multimodal_live/gemini.py
delete mode 100644 src/pipecat/services/google/gemini_live/llm_vertex.py
delete mode 100644 src/pipecat/services/google/google.py
delete mode 100644 src/pipecat/services/google/llm_openai.py
delete mode 100644 src/pipecat/services/google/llm_vertex.py
delete mode 100644 src/pipecat/services/google/openai/__init__.py
delete mode 100644 src/pipecat/services/google/openai/llm.py
delete mode 100644 src/pipecat/services/nim/__init__.py
delete mode 100644 src/pipecat/services/nim/llm.py
delete mode 100644 src/pipecat/services/openai_realtime/__init__.py
delete mode 100644 src/pipecat/services/openai_realtime/azure.py
delete mode 100644 src/pipecat/services/openai_realtime/context.py
delete mode 100644 src/pipecat/services/openai_realtime/events.py
delete mode 100644 src/pipecat/services/openai_realtime/frames.py
delete mode 100644 src/pipecat/services/openai_realtime_beta/__init__.py
delete mode 100644 src/pipecat/services/openai_realtime_beta/azure.py
delete mode 100644 src/pipecat/services/openai_realtime_beta/context.py
delete mode 100644 src/pipecat/services/openai_realtime_beta/events.py
delete mode 100644 src/pipecat/services/openai_realtime_beta/frames.py
delete mode 100644 src/pipecat/services/openai_realtime_beta/openai.py
delete mode 100644 src/pipecat/services/riva/__init__.py
delete mode 100644 src/pipecat/services/riva/stt.py
delete mode 100644 src/pipecat/services/riva/tts.py
delete mode 100644 tests/test_google_llm_openai.py
diff --git a/examples/function-calling/gemini-openai-format.py b/examples/function-calling/gemini-openai-format.py
deleted file mode 100644
index e3b06c0d6..000000000
--- a/examples/function-calling/gemini-openai-format.py
+++ /dev/null
@@ -1,162 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
-
-
-import os
-
-from dotenv import load_dotenv
-from loguru import logger
-
-from pipecat.adapters.schemas.function_schema import FunctionSchema
-from pipecat.adapters.schemas.tools_schema import ToolsSchema
-from pipecat.audio.vad.silero import SileroVADAnalyzer
-from pipecat.frames.frames import LLMRunFrame, TTSSpeakFrame
-from pipecat.pipeline.pipeline import Pipeline
-from pipecat.pipeline.runner import PipelineRunner
-from pipecat.pipeline.task import PipelineParams, PipelineTask
-from pipecat.processors.aggregators.llm_response_universal import (
- LLMContextAggregatorPair,
- LLMUserAggregatorParams,
-)
-from pipecat.processors.aggregators.openai_llm_context import OpenAILLMContext
-from pipecat.runner.types import RunnerArguments
-from pipecat.runner.utils import create_transport
-from pipecat.services.deepgram.stt import DeepgramSTTService
-from pipecat.services.elevenlabs.tts import ElevenLabsTTSService
-from pipecat.services.google.openai.llm import GoogleLLMOpenAIBetaService
-from pipecat.services.llm_service import FunctionCallParams
-from pipecat.transports.base_transport import BaseTransport, TransportParams
-from pipecat.transports.daily.transport import DailyParams
-from pipecat.transports.websocket.fastapi import FastAPIWebsocketParams
-
-load_dotenv(override=True)
-
-
-async def fetch_weather_from_api(params: FunctionCallParams):
- await params.result_callback({"conditions": "nice", "temperature": "75"})
-
-
-# We use lambdas to defer transport parameter creation until the transport
-# type is selected at runtime.
-transport_params = {
- "daily": lambda: DailyParams(
- audio_in_enabled=True,
- audio_out_enabled=True,
- ),
- "twilio": lambda: FastAPIWebsocketParams(
- audio_in_enabled=True,
- audio_out_enabled=True,
- ),
- "webrtc": lambda: TransportParams(
- audio_in_enabled=True,
- audio_out_enabled=True,
- ),
-}
-
-
-async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
- logger.info(f"Starting bot")
-
- stt = DeepgramSTTService(api_key=os.getenv("DEEPGRAM_API_KEY"))
-
- tts = ElevenLabsTTSService(
- api_key=os.getenv("ELEVENLABS_API_KEY", ""),
- settings=ElevenLabsTTSService.Settings(
- voice=os.getenv("ELEVENLABS_VOICE_ID", ""),
- ),
- )
-
- llm = GoogleLLMOpenAIBetaService(
- api_key=os.getenv("GOOGLE_API_KEY"),
- settings=GoogleLLMOpenAIBetaService.Settings(
- system_instruction="You are a helpful assistant in a voice conversation. Your responses will be spoken aloud, so avoid emojis, bullet points, or other formatting that can't be spoken. Respond to what the user said in a creative, helpful, and brief way.",
- ),
- )
- # You can aslo register a function_name of None to get all functions
- # sent to the same callback with an additional function_name parameter.
- llm.register_function("get_current_weather", fetch_weather_from_api)
-
- @llm.event_handler("on_function_calls_started")
- async def on_function_calls_started(service, function_calls):
- await tts.queue_frame(TTSSpeakFrame("Let me check on that."))
-
- weather_function = FunctionSchema(
- name="get_current_weather",
- description="Get the current weather",
- properties={
- "location": {
- "type": "string",
- "description": "The city and state, e.g. San Francisco, CA",
- },
- "format": {
- "type": "string",
- "enum": ["celsius", "fahrenheit"],
- "description": "The temperature unit to use. Infer this from the user's location.",
- },
- },
- required=["location", "format"],
- )
- tools = ToolsSchema(standard_tools=[weather_function])
- messages = [
- {
- "role": "developer",
- "content": "Start a conversation with 'Hey there' to get the current weather.",
- },
- ]
-
- context = OpenAILLMContext(messages, tools)
- user_aggregator, assistant_aggregator = LLMContextAggregatorPair(
- context,
- user_params=LLMUserAggregatorParams(vad_analyzer=SileroVADAnalyzer()),
- )
-
- pipeline = Pipeline(
- [
- transport.input(),
- stt,
- user_aggregator,
- llm,
- tts,
- transport.output(),
- assistant_aggregator,
- ]
- )
-
- task = PipelineTask(
- pipeline,
- params=PipelineParams(
- enable_metrics=True,
- enable_usage_metrics=True,
- ),
- idle_timeout_secs=runner_args.pipeline_idle_timeout_secs,
- )
-
- @transport.event_handler("on_client_connected")
- async def on_client_connected(transport, client):
- logger.info(f"Client connected")
- # Kick off the conversation.
- await task.queue_frames([LLMRunFrame()])
-
- @transport.event_handler("on_client_disconnected")
- async def on_client_disconnected(transport, client):
- logger.info(f"Client disconnected")
- await task.cancel()
-
- runner = PipelineRunner(handle_sigint=runner_args.handle_sigint)
-
- await runner.run(task)
-
-
-async def bot(runner_args: RunnerArguments):
- """Main bot entry point compatible with Pipecat Cloud."""
- transport = await create_transport(runner_args, transport_params)
- await run_bot(transport, runner_args)
-
-
-if __name__ == "__main__":
- from pipecat.runner.run import main
-
- main()
diff --git a/examples/persistent-context/openai-realtime-beta.py b/examples/persistent-context/openai-realtime-beta.py
deleted file mode 100644
index 4b05db618..000000000
--- a/examples/persistent-context/openai-realtime-beta.py
+++ /dev/null
@@ -1,267 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
-
-import asyncio
-import glob
-import json
-import os
-from datetime import datetime
-
-from dotenv import load_dotenv
-from loguru import logger
-
-from pipecat.audio.vad.silero import SileroVADAnalyzer
-from pipecat.frames.frames import LLMRunFrame
-from pipecat.pipeline.pipeline import Pipeline
-from pipecat.pipeline.runner import PipelineRunner
-from pipecat.pipeline.task import PipelineParams, PipelineTask
-from pipecat.processors.aggregators.openai_llm_context import (
- OpenAILLMContext,
-)
-from pipecat.runner.types import RunnerArguments
-from pipecat.runner.utils import create_transport
-from pipecat.services.deepgram.stt import DeepgramSTTService
-from pipecat.services.llm_service import FunctionCallParams
-from pipecat.services.openai_realtime_beta import (
- InputAudioTranscription,
- OpenAIRealtimeBetaLLMService,
- SessionProperties,
- TurnDetection,
-)
-from pipecat.transports.base_transport import BaseTransport, TransportParams
-from pipecat.transports.daily.transport import DailyParams
-from pipecat.transports.websocket.fastapi import FastAPIWebsocketParams
-
-load_dotenv(override=True)
-
-BASE_FILENAME = "/tmp/pipecat_conversation_"
-
-
-async def fetch_weather_from_api(params: FunctionCallParams):
- temperature = 75 if params.arguments["format"] == "fahrenheit" else 24
- await params.result_callback(
- {
- "conditions": "nice",
- "temperature": temperature,
- "format": params.arguments["format"],
- "timestamp": datetime.now().strftime("%Y%m%d_%H%M%S"),
- }
- )
-
-
-async def get_saved_conversation_filenames(params: FunctionCallParams):
- # Construct the full pattern including the BASE_FILENAME
- full_pattern = f"{BASE_FILENAME}*.json"
-
- # Use glob to find all matching files
- matching_files = glob.glob(full_pattern)
- logger.debug(f"matching files: {matching_files}")
-
- await params.result_callback({"filenames": matching_files})
-
-
-async def save_conversation(params: FunctionCallParams):
- timestamp = datetime.now().strftime("%Y-%m-%d_%H:%M:%S")
- filename = f"{BASE_FILENAME}{timestamp}.json"
- logger.debug(
- f"writing conversation to {filename}\n{json.dumps(params.context.messages, indent=4)}"
- )
- try:
- with open(filename, "w") as file:
- messages = params.context.get_messages_for_persistent_storage()
- # remove the last message, which is the instruction we just gave to save the conversation
- messages.pop()
- json.dump(messages, file, indent=2)
- await params.result_callback({"success": True})
- except Exception as e:
- await params.result_callback({"success": False, "error": str(e)})
-
-
-async def load_conversation(params: FunctionCallParams):
- async def _reset():
- filename = params.arguments["filename"]
- logger.debug(f"loading conversation from {filename}")
- try:
- with open(filename, "r") as file:
- params.context.set_messages(json.load(file))
- await params.llm.reset_conversation()
- await params.llm._create_response()
- except Exception as e:
- await params.result_callback({"success": False, "error": str(e)})
-
- asyncio.create_task(_reset())
-
-
-tools = [
- {
- "type": "function",
- "name": "get_current_weather",
- "description": "Get the current weather",
- "parameters": {
- "type": "object",
- "properties": {
- "location": {
- "type": "string",
- "description": "The city and state, e.g. San Francisco, CA",
- },
- "format": {
- "type": "string",
- "enum": ["celsius", "fahrenheit"],
- "description": "The temperature unit to use. Infer this from the users location.",
- },
- },
- "required": ["location", "format"],
- },
- },
- {
- "type": "function",
- "name": "save_conversation",
- "description": "Save the current conversation. Use this function to persist the current conversation to external storage.",
- "parameters": {
- "type": "object",
- "properties": {},
- "required": [],
- },
- },
- {
- "type": "function",
- "name": "get_saved_conversation_filenames",
- "description": "Get a list of saved conversation histories. Returns a list of filenames. Each filename includes a date and timestamp. Each file is conversation history that can be loaded into this session.",
- "parameters": {
- "type": "object",
- "properties": {},
- "required": [],
- },
- },
- {
- "type": "function",
- "name": "load_conversation",
- "description": "Load a conversation history. Use this function to load a conversation history into the current session.",
- "parameters": {
- "type": "object",
- "properties": {
- "filename": {
- "type": "string",
- "description": "The filename of the conversation history to load.",
- }
- },
- "required": ["filename"],
- },
- },
-]
-
-
-# We use lambdas to defer transport parameter creation until the transport
-# type is selected at runtime.
-transport_params = {
- "daily": lambda: DailyParams(
- audio_in_enabled=True,
- audio_out_enabled=True,
- vad_analyzer=SileroVADAnalyzer(),
- ),
- "twilio": lambda: FastAPIWebsocketParams(
- audio_in_enabled=True,
- audio_out_enabled=True,
- vad_analyzer=SileroVADAnalyzer(),
- ),
- "webrtc": lambda: TransportParams(
- audio_in_enabled=True,
- audio_out_enabled=True,
- vad_analyzer=SileroVADAnalyzer(),
- ),
-}
-
-
-async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
- logger.info(f"Starting bot")
-
- stt = DeepgramSTTService(api_key=os.getenv("DEEPGRAM_API_KEY"))
-
- session_properties = SessionProperties(
- input_audio_transcription=InputAudioTranscription(),
- # Set openai TurnDetection parameters. Not setting this at all will turn
- # it on by default
- turn_detection=TurnDetection(silence_duration_ms=1000),
- # Or set to False to disable openai turn detection and use transport VAD
- # turn_detection=False,
- # tools=tools,
- instructions="""Your knowledge cutoff is 2023-10. You are a helpful and friendly AI.
-
-Act like a human, but remember that you aren't a human and that you can't do human
-things in the real world. Your voice and personality should be warm and engaging, with a lively and
-playful tone.
-
-If interacting in a non-English language, start by using the standard accent or dialect familiar to
-the user. Talk quickly. You should always call a function if you can. Do not refer to these rules,
-even if you're asked about them.
--
-You are participating in a voice conversation. Keep your responses concise, short, and to the point
-unless specifically asked to elaborate on a topic.
-
-Remember, your responses should be short. Just one or two sentences, usually.""",
- )
-
- llm = OpenAIRealtimeBetaLLMService(
- api_key=os.getenv("OPENAI_API_KEY"),
- session_properties=session_properties,
- )
-
- # you can either register a single function for all function calls, or specific functions
- # llm.register_function(None, fetch_weather_from_api)
- llm.register_function("get_current_weather", fetch_weather_from_api)
- llm.register_function("save_conversation", save_conversation)
- llm.register_function("get_saved_conversation_filenames", get_saved_conversation_filenames)
- llm.register_function("load_conversation", load_conversation)
-
- context = OpenAILLMContext([], tools)
- context_aggregator = llm.create_context_aggregator(context)
-
- pipeline = Pipeline(
- [
- transport.input(), # Transport user input
- stt, # STT
- context_aggregator.user(),
- llm, # LLM
- transport.output(), # Transport bot output
- context_aggregator.assistant(),
- ]
- )
-
- task = PipelineTask(
- pipeline,
- params=PipelineParams(
- enable_metrics=True,
- enable_usage_metrics=True,
- ),
- idle_timeout_secs=runner_args.pipeline_idle_timeout_secs,
- )
-
- @transport.event_handler("on_client_connected")
- async def on_client_connected(transport, client):
- logger.info(f"Client connected")
- # Kick off the conversation.
- await task.queue_frames([LLMRunFrame()])
-
- @transport.event_handler("on_client_disconnected")
- async def on_client_disconnected(transport, client):
- logger.info(f"Client disconnected")
- await task.cancel()
-
- runner = PipelineRunner(handle_sigint=runner_args.handle_sigint)
-
- await runner.run(task)
-
-
-async def bot(runner_args: RunnerArguments):
- """Main bot entry point compatible with Pipecat Cloud."""
- transport = await create_transport(runner_args, transport_params)
- await run_bot(transport, runner_args)
-
-
-if __name__ == "__main__":
- from pipecat.runner.run import main
-
- main()
diff --git a/examples/realtime/azure-beta.py b/examples/realtime/azure-beta.py
deleted file mode 100644
index 4e9b7bcb1..000000000
--- a/examples/realtime/azure-beta.py
+++ /dev/null
@@ -1,214 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
-
-
-import os
-from datetime import datetime
-
-from dotenv import load_dotenv
-from loguru import logger
-
-from pipecat.adapters.schemas.function_schema import FunctionSchema
-from pipecat.adapters.schemas.tools_schema import ToolsSchema
-from pipecat.audio.vad.silero import SileroVADAnalyzer
-from pipecat.frames.frames import LLMRunFrame
-from pipecat.pipeline.pipeline import Pipeline
-from pipecat.pipeline.runner import PipelineRunner
-from pipecat.pipeline.task import PipelineParams, PipelineTask
-from pipecat.processors.aggregators.openai_llm_context import OpenAILLMContext
-from pipecat.runner.types import RunnerArguments
-from pipecat.runner.utils import create_transport
-from pipecat.services.llm_service import FunctionCallParams
-from pipecat.services.openai_realtime_beta import (
- AzureRealtimeBetaLLMService,
- InputAudioTranscription,
- SessionProperties,
-)
-from pipecat.transports.base_transport import BaseTransport, TransportParams
-from pipecat.transports.daily.transport import DailyParams
-from pipecat.transports.websocket.fastapi import FastAPIWebsocketParams
-
-load_dotenv(override=True)
-
-
-async def fetch_weather_from_api(params: FunctionCallParams):
- temperature = 75 if params.arguments["format"] == "fahrenheit" else 24
- await params.result_callback(
- {
- "conditions": "nice",
- "temperature": temperature,
- "format": params.arguments["format"],
- "timestamp": datetime.now().strftime("%Y%m%d_%H%M%S"),
- }
- )
-
-
-async def fetch_restaurant_recommendation(params: FunctionCallParams):
- await params.result_callback({"name": "The Golden Dragon"})
-
-
-# Define weather function using standardized schema
-weather_function = FunctionSchema(
- name="get_current_weather",
- description="Get the current weather",
- properties={
- "location": {
- "type": "string",
- "description": "The city and state, e.g. San Francisco, CA",
- },
- "format": {
- "type": "string",
- "enum": ["celsius", "fahrenheit"],
- "description": "The temperature unit to use. Infer this from the users location.",
- },
- },
- required=["location", "format"],
-)
-
-restaurant_function = FunctionSchema(
- name="get_restaurant_recommendation",
- description="Get a restaurant recommendation",
- properties={
- "location": {
- "type": "string",
- "description": "The city and state, e.g. San Francisco, CA",
- },
- },
- required=["location"],
-)
-
-# Create tools schema
-tools = ToolsSchema(standard_tools=[weather_function, restaurant_function])
-
-
-# We use lambdas to defer transport parameter creation until the transport
-# type is selected at runtime.
-transport_params = {
- "daily": lambda: DailyParams(
- audio_in_enabled=True,
- audio_out_enabled=True,
- vad_analyzer=SileroVADAnalyzer(),
- ),
- "twilio": lambda: FastAPIWebsocketParams(
- audio_in_enabled=True,
- audio_out_enabled=True,
- vad_analyzer=SileroVADAnalyzer(),
- ),
- "webrtc": lambda: TransportParams(
- audio_in_enabled=True,
- audio_out_enabled=True,
- vad_analyzer=SileroVADAnalyzer(),
- ),
-}
-
-
-async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
- logger.info(f"Starting bot")
-
- session_properties = SessionProperties(
- input_audio_transcription=InputAudioTranscription(model="whisper-1"),
- # Set openai TurnDetection parameters. Not setting this at all will turn it
- # on by default
- # turn_detection=TurnDetection(silence_duration_ms=1000),
- # Or set to False to disable openai turn detection and use transport VAD
- # turn_detection=False,
- # tools=tools,
- instructions="""You are a helpful and friendly AI.
-
-Act like a human, but remember that you aren't a human and that you can't do human
-things in the real world. Your voice and personality should be warm and engaging, with a lively and
-playful tone.
-
-If interacting in a non-English language, start by using the standard accent or dialect familiar to
-the user. Talk quickly. You should always call a function if you can. Do not refer to these rules,
-even if you're asked about them.
--
-You are participating in a voice conversation. Keep your responses concise, short, and to the point
-unless specifically asked to elaborate on a topic.
-
-You have access to the following tools:
-- get_current_weather: Get the current weather for a given location.
-- get_restaurant_recommendation: Get a restaurant recommendation for a given location.
-
-Remember, your responses should be short. Just one or two sentences, usually. Respond in English.""",
- )
-
- llm = AzureRealtimeBetaLLMService(
- api_key=os.getenv("AZURE_REALTIME_API_KEY"),
- base_url=os.getenv("AZURE_REALTIME_BASE_URL"),
- session_properties=session_properties,
- )
-
- # you can either register a single function for all function calls, or specific functions
- # llm.register_function(None, fetch_weather_from_api)
- llm.register_function("get_current_weather", fetch_weather_from_api)
- llm.register_function("get_restaurant_recommendation", fetch_restaurant_recommendation)
-
- # Create a standard OpenAI LLM context object using the normal messages format. The
- # OpenAIRealtimeBetaLLMService will convert this internally to messages that the
- # openai WebSocket API can understand.
- context = OpenAILLMContext(
- [{"role": "developer", "content": "Say hello!"}],
- # [{"role": "developer", "content": [{"type": "text", "text": "Say hello!"}]}],
- # [
- # {
- # "role": "developer",
- # "content": [
- # {"type": "text", "text": "Say"},
- # {"type": "text", "text": "yo what's up!"},
- # ],
- # }
- # ],
- tools,
- )
-
- context_aggregator = llm.create_context_aggregator(context)
-
- pipeline = Pipeline(
- [
- transport.input(), # Transport user input
- context_aggregator.user(),
- llm, # LLM
- transport.output(), # Transport bot output
- context_aggregator.assistant(),
- ]
- )
-
- task = PipelineTask(
- pipeline,
- params=PipelineParams(
- enable_metrics=True,
- enable_usage_metrics=True,
- ),
- idle_timeout_secs=runner_args.pipeline_idle_timeout_secs,
- )
-
- @transport.event_handler("on_client_connected")
- async def on_client_connected(transport, client):
- logger.info(f"Client connected")
- # Kick off the conversation.
- await task.queue_frames([LLMRunFrame()])
-
- @transport.event_handler("on_client_disconnected")
- async def on_client_disconnected(transport, client):
- logger.info(f"Client disconnected")
- await task.cancel()
-
- runner = PipelineRunner(handle_sigint=runner_args.handle_sigint)
-
- await runner.run(task)
-
-
-async def bot(runner_args: RunnerArguments):
- """Main bot entry point compatible with Pipecat Cloud."""
- transport = await create_transport(runner_args, transport_params)
- await run_bot(transport, runner_args)
-
-
-if __name__ == "__main__":
- from pipecat.runner.run import main
-
- main()
diff --git a/examples/realtime/openai-beta-text.py b/examples/realtime/openai-beta-text.py
deleted file mode 100644
index 31f5d0560..000000000
--- a/examples/realtime/openai-beta-text.py
+++ /dev/null
@@ -1,215 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
-
-
-import os
-from datetime import datetime
-
-from dotenv import load_dotenv
-from loguru import logger
-
-from pipecat.adapters.schemas.function_schema import FunctionSchema
-from pipecat.adapters.schemas.tools_schema import ToolsSchema
-from pipecat.audio.vad.silero import SileroVADAnalyzer
-from pipecat.frames.frames import LLMRunFrame
-from pipecat.pipeline.pipeline import Pipeline
-from pipecat.pipeline.runner import PipelineRunner
-from pipecat.pipeline.task import PipelineParams, PipelineTask
-from pipecat.processors.aggregators.openai_llm_context import OpenAILLMContext
-from pipecat.runner.types import RunnerArguments
-from pipecat.runner.utils import create_transport
-from pipecat.services.cartesia.tts import CartesiaTTSService
-from pipecat.services.llm_service import FunctionCallParams
-from pipecat.services.openai_realtime_beta import (
- InputAudioNoiseReduction,
- InputAudioTranscription,
- OpenAIRealtimeBetaLLMService,
- SemanticTurnDetection,
- SessionProperties,
-)
-from pipecat.transports.base_transport import BaseTransport, TransportParams
-from pipecat.transports.daily.transport import DailyParams
-from pipecat.transports.websocket.fastapi import FastAPIWebsocketParams
-
-load_dotenv(override=True)
-
-
-async def fetch_weather_from_api(params: FunctionCallParams):
- temperature = 75 if params.arguments["format"] == "fahrenheit" else 24
- await params.result_callback(
- {
- "conditions": "nice",
- "temperature": temperature,
- "format": params.arguments["format"],
- "timestamp": datetime.now().strftime("%Y%m%d_%H%M%S"),
- }
- )
-
-
-async def fetch_restaurant_recommendation(params: FunctionCallParams):
- await params.result_callback({"name": "The Golden Dragon"})
-
-
-weather_function = FunctionSchema(
- name="get_current_weather",
- description="Get the current weather",
- properties={
- "location": {
- "type": "string",
- "description": "The city and state, e.g. San Francisco, CA",
- },
- "format": {
- "type": "string",
- "enum": ["celsius", "fahrenheit"],
- "description": "The temperature unit to use. Infer this from the users location.",
- },
- },
- required=["location", "format"],
-)
-
-restaurant_function = FunctionSchema(
- name="get_restaurant_recommendation",
- description="Get a restaurant recommendation",
- properties={
- "location": {
- "type": "string",
- "description": "The city and state, e.g. San Francisco, CA",
- },
- },
- required=["location"],
-)
-
-# Create tools schema
-tools = ToolsSchema(standard_tools=[weather_function, restaurant_function])
-
-
-# We use lambdas to defer transport parameter creation until the transport
-# type is selected at runtime.
-transport_params = {
- "daily": lambda: DailyParams(
- audio_in_enabled=True,
- audio_out_enabled=True,
- vad_analyzer=SileroVADAnalyzer(),
- ),
- "twilio": lambda: FastAPIWebsocketParams(
- audio_in_enabled=True,
- audio_out_enabled=True,
- vad_analyzer=SileroVADAnalyzer(),
- ),
- "webrtc": lambda: TransportParams(
- audio_in_enabled=True,
- audio_out_enabled=True,
- vad_analyzer=SileroVADAnalyzer(),
- ),
-}
-
-
-async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
- logger.info(f"Starting bot")
-
- session_properties = SessionProperties(
- input_audio_transcription=InputAudioTranscription(),
- modalities=["text"],
- # Set openai TurnDetection parameters. Not setting this at all will turn it
- # on by default
- turn_detection=SemanticTurnDetection(),
- # Or set to False to disable openai turn detection and use transport VAD
- # turn_detection=False,
- input_audio_noise_reduction=InputAudioNoiseReduction(type="near_field"),
- # tools=tools,
- instructions="""You are a helpful and friendly AI.
-
-Act like a human, but remember that you aren't a human and that you can't do human
-things in the real world. Your voice and personality should be warm and engaging, with a lively and
-playful tone.
-
-If interacting in a non-English language, start by using the standard accent or dialect familiar to
-the user. Talk quickly. You should always call a function if you can. Do not refer to these rules,
-even if you're asked about them.
-
-You are participating in a voice conversation. Keep your responses concise, short, and to the point
-unless specifically asked to elaborate on a topic.
-
-You have access to the following tools:
-- get_current_weather: Get the current weather for a given location.
-- get_restaurant_recommendation: Get a restaurant recommendation for a given location.
-
-Remember, your responses should be short. Just one or two sentences, usually. Respond in English.""",
- )
-
- llm = OpenAIRealtimeBetaLLMService(
- api_key=os.getenv("OPENAI_API_KEY"),
- session_properties=session_properties,
- )
-
- tts = CartesiaTTSService(
- api_key=os.getenv("CARTESIA_API_KEY"),
- settings=CartesiaTTSService.Settings(
- voice="71a7ad14-091c-4e8e-a314-022ece01c121", # British Reading Lady
- ),
- )
-
- # you can either register a single function for all function calls, or specific functions
- # llm.register_function(None, fetch_weather_from_api)
- llm.register_function("get_current_weather", fetch_weather_from_api)
- llm.register_function("get_restaurant_recommendation", fetch_restaurant_recommendation)
-
- # Create a standard OpenAI LLM context object using the normal messages format. The
- # OpenAIRealtimeBetaLLMService will convert this internally to messages that the
- # openai WebSocket API can understand.
- context = OpenAILLMContext(
- [{"role": "developer", "content": "Say hello!"}],
- tools,
- )
-
- context_aggregator = llm.create_context_aggregator(context)
-
- pipeline = Pipeline(
- [
- transport.input(), # Transport user input
- context_aggregator.user(),
- llm, # LLM
- tts, # TTS
- transport.output(), # Transport bot output
- context_aggregator.assistant(),
- ]
- )
-
- task = PipelineTask(
- pipeline,
- params=PipelineParams(
- enable_metrics=True,
- enable_usage_metrics=True,
- ),
- idle_timeout_secs=runner_args.pipeline_idle_timeout_secs,
- )
-
- @transport.event_handler("on_client_connected")
- async def on_client_connected(transport, client):
- logger.info(f"Client connected")
- # Kick off the conversation.
- await task.queue_frames([LLMRunFrame()])
-
- @transport.event_handler("on_client_disconnected")
- async def on_client_disconnected(transport, client):
- logger.info(f"Client disconnected")
- await task.cancel()
-
- runner = PipelineRunner(handle_sigint=runner_args.handle_sigint)
-
- await runner.run(task)
-
-
-async def bot(runner_args: RunnerArguments):
- """Main bot entry point compatible with Pipecat Cloud."""
- transport = await create_transport(runner_args, transport_params)
- await run_bot(transport, runner_args)
-
-
-if __name__ == "__main__":
- from pipecat.runner.run import main
-
- main()
diff --git a/examples/realtime/openai-beta.py b/examples/realtime/openai-beta.py
deleted file mode 100644
index 4d1714fe3..000000000
--- a/examples/realtime/openai-beta.py
+++ /dev/null
@@ -1,219 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
-
-
-import os
-from datetime import datetime
-
-from dotenv import load_dotenv
-from loguru import logger
-
-from pipecat.adapters.schemas.function_schema import FunctionSchema
-from pipecat.adapters.schemas.tools_schema import ToolsSchema
-from pipecat.audio.vad.silero import SileroVADAnalyzer
-from pipecat.frames.frames import LLMRunFrame, TranscriptionMessage
-from pipecat.pipeline.pipeline import Pipeline
-from pipecat.pipeline.runner import PipelineRunner
-from pipecat.pipeline.task import PipelineParams, PipelineTask
-from pipecat.processors.aggregators.openai_llm_context import OpenAILLMContext
-from pipecat.processors.transcript_processor import TranscriptProcessor
-from pipecat.runner.types import RunnerArguments
-from pipecat.runner.utils import create_transport
-from pipecat.services.llm_service import FunctionCallParams
-from pipecat.services.openai_realtime_beta import (
- InputAudioNoiseReduction,
- InputAudioTranscription,
- OpenAIRealtimeBetaLLMService,
- SemanticTurnDetection,
- SessionProperties,
-)
-from pipecat.transports.base_transport import BaseTransport, TransportParams
-from pipecat.transports.daily.transport import DailyParams
-from pipecat.transports.websocket.fastapi import FastAPIWebsocketParams
-
-load_dotenv(override=True)
-
-
-async def fetch_weather_from_api(params: FunctionCallParams):
- temperature = 75 if params.arguments["format"] == "fahrenheit" else 24
- await params.result_callback(
- {
- "conditions": "nice",
- "temperature": temperature,
- "format": params.arguments["format"],
- "timestamp": datetime.now().strftime("%Y%m%d_%H%M%S"),
- }
- )
-
-
-async def fetch_restaurant_recommendation(params: FunctionCallParams):
- await params.result_callback({"name": "The Golden Dragon"})
-
-
-weather_function = FunctionSchema(
- name="get_current_weather",
- description="Get the current weather",
- properties={
- "location": {
- "type": "string",
- "description": "The city and state, e.g. San Francisco, CA",
- },
- "format": {
- "type": "string",
- "enum": ["celsius", "fahrenheit"],
- "description": "The temperature unit to use. Infer this from the users location.",
- },
- },
- required=["location", "format"],
-)
-
-restaurant_function = FunctionSchema(
- name="get_restaurant_recommendation",
- description="Get a restaurant recommendation",
- properties={
- "location": {
- "type": "string",
- "description": "The city and state, e.g. San Francisco, CA",
- },
- },
- required=["location"],
-)
-
-# Create tools schema
-tools = ToolsSchema(standard_tools=[weather_function, restaurant_function])
-
-
-# We use lambdas to defer transport parameter creation until the transport
-# type is selected at runtime.
-transport_params = {
- "daily": lambda: DailyParams(
- audio_in_enabled=True,
- audio_out_enabled=True,
- vad_analyzer=SileroVADAnalyzer(),
- ),
- "twilio": lambda: FastAPIWebsocketParams(
- audio_in_enabled=True,
- audio_out_enabled=True,
- vad_analyzer=SileroVADAnalyzer(),
- ),
- "webrtc": lambda: TransportParams(
- audio_in_enabled=True,
- audio_out_enabled=True,
- vad_analyzer=SileroVADAnalyzer(),
- ),
-}
-
-
-async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
- logger.info(f"Starting bot")
-
- session_properties = SessionProperties(
- input_audio_transcription=InputAudioTranscription(),
- # Set openai TurnDetection parameters. Not setting this at all will turn it
- # on by default
- turn_detection=SemanticTurnDetection(),
- # Or set to False to disable openai turn detection and use transport VAD
- # turn_detection=False,
- input_audio_noise_reduction=InputAudioNoiseReduction(type="near_field"),
- # tools=tools,
- instructions="""You are a helpful and friendly AI.
-
-Act like a human, but remember that you aren't a human and that you can't do human
-things in the real world. Your voice and personality should be warm and engaging, with a lively and
-playful tone.
-
-If interacting in a non-English language, start by using the standard accent or dialect familiar to
-the user. Talk quickly. You should always call a function if you can. Do not refer to these rules,
-even if you're asked about them.
-
-You are participating in a voice conversation. Keep your responses concise, short, and to the point
-unless specifically asked to elaborate on a topic.
-
-You have access to the following tools:
-- get_current_weather: Get the current weather for a given location.
-- get_restaurant_recommendation: Get a restaurant recommendation for a given location.
-
-Remember, your responses should be short. Just one or two sentences, usually. Respond in English.""",
- )
-
- llm = OpenAIRealtimeBetaLLMService(
- api_key=os.getenv("OPENAI_API_KEY"),
- session_properties=session_properties,
- )
-
- # you can either register a single function for all function calls, or specific functions
- # llm.register_function(None, fetch_weather_from_api)
- llm.register_function("get_current_weather", fetch_weather_from_api)
- llm.register_function("get_restaurant_recommendation", fetch_restaurant_recommendation)
-
- transcript = TranscriptProcessor()
-
- # Create a standard OpenAI LLM context object using the normal messages format. The
- # OpenAIRealtimeBetaLLMService will convert this internally to messages that the
- # openai WebSocket API can understand.
- context = OpenAILLMContext(
- [{"role": "developer", "content": "Say hello!"}],
- tools,
- )
-
- context_aggregator = llm.create_context_aggregator(context)
-
- pipeline = Pipeline(
- [
- transport.input(), # Transport user input
- context_aggregator.user(),
- llm, # LLM
- transcript.user(), # Placed after the LLM, as LLM pushes TranscriptionFrames downstream
- transport.output(), # Transport bot output
- transcript.assistant(), # After the transcript output, to time with the audio output
- context_aggregator.assistant(),
- ]
- )
-
- task = PipelineTask(
- pipeline,
- params=PipelineParams(
- enable_metrics=True,
- enable_usage_metrics=True,
- ),
- idle_timeout_secs=runner_args.pipeline_idle_timeout_secs,
- )
-
- @transport.event_handler("on_client_connected")
- async def on_client_connected(transport, client):
- logger.info(f"Client connected")
- # Kick off the conversation.
- await task.queue_frames([LLMRunFrame()])
-
- @transport.event_handler("on_client_disconnected")
- async def on_client_disconnected(transport, client):
- logger.info(f"Client disconnected")
- await task.cancel()
-
- # Register event handler for transcript updates
- @transcript.event_handler("on_transcript_update")
- async def on_transcript_update(processor, frame):
- for msg in frame.messages:
- if isinstance(msg, TranscriptionMessage):
- timestamp = f"[{msg.timestamp}] " if msg.timestamp else ""
- line = f"{timestamp}{msg.role}: {msg.content}"
- logger.info(f"Transcript: {line}")
-
- runner = PipelineRunner(handle_sigint=runner_args.handle_sigint)
-
- await runner.run(task)
-
-
-async def bot(runner_args: RunnerArguments):
- """Main bot entry point compatible with Pipecat Cloud."""
- transport = await create_transport(runner_args, transport_params)
- await run_bot(transport, runner_args)
-
-
-if __name__ == "__main__":
- from pipecat.runner.run import main
-
- main()
diff --git a/src/pipecat/services/ai_services.py b/src/pipecat/services/ai_services.py
deleted file mode 100644
index 5f7b6d893..000000000
--- a/src/pipecat/services/ai_services.py
+++ /dev/null
@@ -1,33 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
-
-"""Deprecated AI services module.
-
-This module is deprecated. Import services directly from their respective modules:
-- pipecat.services.ai_service
-- pipecat.services.image_service
-- pipecat.services.llm_service
-- pipecat.services.stt_service
-- pipecat.services.tts_service
-- pipecat.services.vision_service
-"""
-
-import sys
-
-from pipecat.services import DeprecatedModuleProxy
-
-from .ai_service import *
-from .image_service import *
-from .llm_service import *
-from .stt_service import *
-from .tts_service import *
-from .vision_service import *
-
-sys.modules[__name__] = DeprecatedModuleProxy(
- globals(),
- "ai_services",
- "[ai_service,image_service,llm_service,stt_service,tts_service,vision_service]",
-)
diff --git a/src/pipecat/services/aws_nova_sonic/__init__.py b/src/pipecat/services/aws_nova_sonic/__init__.py
deleted file mode 100644
index a198094cb..000000000
--- a/src/pipecat/services/aws_nova_sonic/__init__.py
+++ /dev/null
@@ -1,24 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
-
-import warnings
-
-from pipecat.services.aws.nova_sonic.llm import AWSNovaSonicLLMService, Params
-
-with warnings.catch_warnings():
- warnings.simplefilter("always")
- warnings.warn(
- "Types in pipecat.services.aws_nova_sonic are deprecated. "
- "Please use the equivalent types from "
- "pipecat.services.aws.nova_sonic.llm instead.",
- DeprecationWarning,
- stacklevel=2,
- )
-
-__all__ = [
- "AWSNovaSonicLLMService",
- "Params",
-]
diff --git a/src/pipecat/services/aws_nova_sonic/aws.py b/src/pipecat/services/aws_nova_sonic/aws.py
deleted file mode 100644
index b69323b8d..000000000
--- a/src/pipecat/services/aws_nova_sonic/aws.py
+++ /dev/null
@@ -1,25 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
-
-"""AWS Nova Sonic LLM service implementation for Pipecat AI framework.
-
-This module provides a speech-to-speech LLM service using AWS Nova Sonic, which supports
-bidirectional audio streaming, text generation, and function calling capabilities.
-"""
-
-import warnings
-
-from pipecat.services.aws.nova_sonic.llm import *
-
-with warnings.catch_warnings():
- warnings.simplefilter("always")
- warnings.warn(
- "Types in pipecat.services.aws_nova_sonic.aws are deprecated. "
- "Please use the equivalent types from "
- "pipecat.services.aws.nova_sonic.llm instead.",
- DeprecationWarning,
- stacklevel=2,
- )
diff --git a/src/pipecat/services/aws_nova_sonic/context.py b/src/pipecat/services/aws_nova_sonic/context.py
deleted file mode 100644
index 01f152b16..000000000
--- a/src/pipecat/services/aws_nova_sonic/context.py
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
-
-"""Context management for AWS Nova Sonic LLM service.
-
-This module provides specialized context aggregators and message handling for AWS Nova Sonic,
-including conversation history management and role-specific message processing.
-
-.. deprecated:: 0.0.91
- AWS Nova Sonic no longer uses types from this module under the hood.
- It now uses `LLMContext` and `LLMContextAggregatorPair`.
- Using the new patterns should allow you to not need types from this module.
-
- See deprecation warning in pipecat.services.aws.nova_sonic.context for more
- details.
-"""
-
-from pipecat.services.aws.nova_sonic.context import *
diff --git a/src/pipecat/services/aws_nova_sonic/frames.py b/src/pipecat/services/aws_nova_sonic/frames.py
deleted file mode 100644
index 7ac81215c..000000000
--- a/src/pipecat/services/aws_nova_sonic/frames.py
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
-
-"""Custom frames for AWS Nova Sonic LLM service."""
-
-import warnings
-
-from pipecat.services.aws.nova_sonic.frames import *
-
-with warnings.catch_warnings():
- warnings.simplefilter("always")
- warnings.warn(
- "Types in pipecat.services.aws_nova_sonic.frames are deprecated. "
- "Please use the equivalent types from "
- "pipecat.services.aws.nova_sonic.frames instead.",
- DeprecationWarning,
- stacklevel=2,
- )
diff --git a/src/pipecat/services/deepgram/stt_sagemaker.py b/src/pipecat/services/deepgram/stt_sagemaker.py
deleted file mode 100644
index 08cd0c5d3..000000000
--- a/src/pipecat/services/deepgram/stt_sagemaker.py
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
-
-"""Deprecated: use ``pipecat.services.deepgram.sagemaker.stt`` instead."""
-
-import warnings
-
-warnings.warn(
- "Module `pipecat.services.deepgram.stt_sagemaker` is deprecated, "
- "use `pipecat.services.deepgram.sagemaker.stt` instead.",
- DeprecationWarning,
- stacklevel=2,
-)
-
-from pipecat.services.deepgram.sagemaker.stt import * # noqa: E402, F401, F403
diff --git a/src/pipecat/services/deepgram/tts_sagemaker.py b/src/pipecat/services/deepgram/tts_sagemaker.py
deleted file mode 100644
index 61ca2bceb..000000000
--- a/src/pipecat/services/deepgram/tts_sagemaker.py
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
-
-"""Deprecated: use ``pipecat.services.deepgram.sagemaker.tts`` instead."""
-
-import warnings
-
-warnings.warn(
- "Module `pipecat.services.deepgram.tts_sagemaker` is deprecated, "
- "use `pipecat.services.deepgram.sagemaker.tts` instead.",
- DeprecationWarning,
- stacklevel=2,
-)
-
-from pipecat.services.deepgram.sagemaker.tts import * # noqa: E402, F401, F403
diff --git a/src/pipecat/services/gemini_multimodal_live/__init__.py b/src/pipecat/services/gemini_multimodal_live/__init__.py
deleted file mode 100644
index ac4524606..000000000
--- a/src/pipecat/services/gemini_multimodal_live/__init__.py
+++ /dev/null
@@ -1,7 +0,0 @@
-from .file_api import GeminiFileAPI
-from .gemini import GeminiMultimodalLiveLLMService
-
-__all__ = [
- "GeminiFileAPI",
- "GeminiMultimodalLiveLLMService",
-]
diff --git a/src/pipecat/services/gemini_multimodal_live/events.py b/src/pipecat/services/gemini_multimodal_live/events.py
deleted file mode 100644
index a560a0b02..000000000
--- a/src/pipecat/services/gemini_multimodal_live/events.py
+++ /dev/null
@@ -1,44 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
-
-"""Event models and utilities for Google Gemini Multimodal Live API.
-
-.. deprecated:: 0.0.90
- Importing StartSensitivity and EndSensitivity from this module is deprecated.
- Import them directly from google.genai.types instead.
-"""
-
-import warnings
-
-from loguru import logger
-
-try:
- from google.genai.types import (
- EndSensitivity as _EndSensitivity,
- )
- from google.genai.types import (
- StartSensitivity as _StartSensitivity,
- )
-except ModuleNotFoundError as e:
- logger.error(f"Exception: {e}")
- logger.error("In order to use Google AI, you need to `pip install pipecat-ai[google]`.")
- raise Exception(f"Missing module: {e}")
-
-# These aliases are just here for backward compatibility, since we used to
-# define public-facing StartSensitivity and EndSensitivity enums in this
-# module.
-with warnings.catch_warnings():
- warnings.simplefilter("always")
- warnings.warn(
- "Importing StartSensitivity and EndSensitivity from "
- "pipecat.services.gemini_multimodal_live.events is deprecated. "
- "Please import them directly from google.genai.types instead.",
- DeprecationWarning,
- stacklevel=2,
- )
-
-StartSensitivity = _StartSensitivity
-EndSensitivity = _EndSensitivity
diff --git a/src/pipecat/services/gemini_multimodal_live/file_api.py b/src/pipecat/services/gemini_multimodal_live/file_api.py
deleted file mode 100644
index 02df16ded..000000000
--- a/src/pipecat/services/gemini_multimodal_live/file_api.py
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
-
-"""Gemini File API client for uploading and managing files.
-
-This module provides a client for Google's Gemini File API, enabling file
-uploads, metadata retrieval, listing, and deletion. Files uploaded through
-this API can be referenced in Gemini generative model calls.
-
-.. deprecated:: 0.0.90
- Importing GeminiFileAPI from this module is deprecated.
- Import it from pipecat.services.google.gemini_live.file_api instead.
-"""
-
-import warnings
-
-from loguru import logger
-
-try:
- from pipecat.services.google.gemini_live.file_api import GeminiFileAPI as _GeminiFileAPI
-except ModuleNotFoundError as e:
- logger.error(f"Exception: {e}")
- logger.error("In order to use Google AI, you need to `pip install pipecat-ai[google]`.")
- raise Exception(f"Missing module: {e}")
-
-# These aliases are just here for backward compatibility, since we used to
-# define public-facing StartSensitivity and EndSensitivity enums in this
-# module.
-warnings.warn(
- "Importing GeminiFileAPI from "
- "pipecat.services.gemini_multimodal_live.file_api is deprecated. "
- "Please import it from pipecat.services.google.gemini_live.file_api instead.",
- DeprecationWarning,
- stacklevel=2,
-)
-GeminiFileAPI = _GeminiFileAPI
diff --git a/src/pipecat/services/gemini_multimodal_live/gemini.py b/src/pipecat/services/gemini_multimodal_live/gemini.py
deleted file mode 100644
index 6f01e5a23..000000000
--- a/src/pipecat/services/gemini_multimodal_live/gemini.py
+++ /dev/null
@@ -1,57 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
-
-"""Google Gemini Live API service implementation.
-
-This module provides real-time conversational AI capabilities using Google's
-Gemini Live API, supporting both text and audio modalities with
-voice transcription, streaming responses, and tool usage.
-
-.. deprecated:: 0.0.90
- This module is deprecated. Please use the equivalent types from
- pipecat.services.google.gemini_live.llm instead. Note that the new type names
- do not include 'Multimodal'.
-"""
-
-import warnings
-
-from pipecat.services.google.gemini_live.llm import (
- ContextWindowCompressionParams as _ContextWindowCompressionParams,
-)
-from pipecat.services.google.gemini_live.llm import (
- GeminiLiveAssistantContextAggregator,
- GeminiLiveContext,
- GeminiLiveContextAggregatorPair,
- GeminiLiveLLMService,
- GeminiLiveUserContextAggregator,
- GeminiModalities,
-)
-from pipecat.services.google.gemini_live.llm import GeminiMediaResolution as _GeminiMediaResolution
-from pipecat.services.google.gemini_live.llm import GeminiVADParams as _GeminiVADParams
-from pipecat.services.google.gemini_live.llm import InputParams as _InputParams
-
-with warnings.catch_warnings():
- warnings.simplefilter("always")
- warnings.warn(
- "Types in pipecat.services.gemini_multimodal_live.gemini are deprecated. "
- "Please use the equivalent types from "
- "pipecat.services.google.gemini_live.llm instead. Note that the new type "
- "names do not include 'Multimodal' "
- "(e.g. `GeminiMultimodalLiveLLMService` is now `GeminiLiveLLMService`).",
- DeprecationWarning,
- stacklevel=2,
- )
-
-GeminiMultimodalLiveContext = GeminiLiveContext
-GeminiMultimodalLiveUserContextAggregator = GeminiLiveUserContextAggregator
-GeminiMultimodalLiveAssistantContextAggregator = GeminiLiveAssistantContextAggregator
-GeminiMultimodalLiveContextAggregatorPair = GeminiLiveContextAggregatorPair
-GeminiMultimodalModalities = GeminiModalities
-GeminiMediaResolution = _GeminiMediaResolution
-GeminiVADParams = _GeminiVADParams
-ContextWindowCompressionParams = _ContextWindowCompressionParams
-InputParams = _InputParams
-GeminiMultimodalLiveLLMService = GeminiLiveLLMService
diff --git a/src/pipecat/services/google/__init__.py b/src/pipecat/services/google/__init__.py
index 32b12e367..95812a536 100644
--- a/src/pipecat/services/google/__init__.py
+++ b/src/pipecat/services/google/__init__.py
@@ -12,12 +12,11 @@ from .frames import *
from .gemini_live import *
from .image import *
from .llm import *
-from .openai import *
from .rtvi import *
from .stt import *
from .tts import *
from .vertex import *
sys.modules[__name__] = DeprecatedModuleProxy(
- globals(), "google", "google.[frames,image,llm,openai,vertex,rtvi,stt,tts]"
+ globals(), "google", "google.[frames,image,llm,vertex,rtvi,stt,tts]"
)
diff --git a/src/pipecat/services/google/gemini_live/llm_vertex.py b/src/pipecat/services/google/gemini_live/llm_vertex.py
deleted file mode 100644
index 038d72e57..000000000
--- a/src/pipecat/services/google/gemini_live/llm_vertex.py
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
-
-"""Deprecated: use ``pipecat.services.google.gemini_live.vertex.llm`` instead."""
-
-import warnings
-
-warnings.warn(
- "Module `pipecat.services.google.gemini_live.llm_vertex` is deprecated, "
- "use `pipecat.services.google.gemini_live.vertex.llm` instead.",
- DeprecationWarning,
- stacklevel=2,
-)
-
-from pipecat.services.google.gemini_live.vertex.llm import * # noqa: E402, F401, F403
diff --git a/src/pipecat/services/google/google.py b/src/pipecat/services/google/google.py
deleted file mode 100644
index b2fc88b23..000000000
--- a/src/pipecat/services/google/google.py
+++ /dev/null
@@ -1,24 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
-
-"""Google services module for Pipecat."""
-
-import sys
-
-from pipecat.services import DeprecatedModuleProxy
-
-from .frames import *
-from .image import *
-from .llm import *
-from .openai import *
-from .rtvi import *
-from .stt import *
-from .tts import *
-from .vertex import *
-
-sys.modules[__name__] = DeprecatedModuleProxy(
- globals(), "google", "google.[frames,image,llm,openai,vertex,rtvi,stt,tts]"
-)
diff --git a/src/pipecat/services/google/llm_openai.py b/src/pipecat/services/google/llm_openai.py
deleted file mode 100644
index f9d182e78..000000000
--- a/src/pipecat/services/google/llm_openai.py
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
-
-"""Deprecated: use ``pipecat.services.google.openai.llm`` instead."""
-
-import warnings
-
-warnings.warn(
- "Module `pipecat.services.google.llm_openai` is deprecated, "
- "use `pipecat.services.google.openai.llm` instead.",
- DeprecationWarning,
- stacklevel=2,
-)
-
-from pipecat.services.google.openai.llm import * # noqa: E402, F401, F403
diff --git a/src/pipecat/services/google/llm_vertex.py b/src/pipecat/services/google/llm_vertex.py
deleted file mode 100644
index 54d338ad7..000000000
--- a/src/pipecat/services/google/llm_vertex.py
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
-
-"""Deprecated: use ``pipecat.services.google.vertex.llm`` instead."""
-
-import warnings
-
-warnings.warn(
- "Module `pipecat.services.google.llm_vertex` is deprecated, "
- "use `pipecat.services.google.vertex.llm` instead.",
- DeprecationWarning,
- stacklevel=2,
-)
-
-from pipecat.services.google.vertex.llm import * # noqa: E402, F401, F403
diff --git a/src/pipecat/services/google/openai/__init__.py b/src/pipecat/services/google/openai/__init__.py
deleted file mode 100644
index c4d243b97..000000000
--- a/src/pipecat/services/google/openai/__init__.py
+++ /dev/null
@@ -1,5 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
diff --git a/src/pipecat/services/google/openai/llm.py b/src/pipecat/services/google/openai/llm.py
deleted file mode 100644
index 08a7bcd1b..000000000
--- a/src/pipecat/services/google/openai/llm.py
+++ /dev/null
@@ -1,217 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
-
-"""Google LLM service using OpenAI-compatible API format.
-
-This module provides integration with Google's AI LLM models using the OpenAI
-API format through Google's Gemini API OpenAI compatibility layer.
-"""
-
-import json
-import os
-from dataclasses import dataclass
-from typing import Optional
-
-from openai import AsyncStream
-from openai.types.chat import ChatCompletionChunk
-
-from pipecat.services.llm_service import FunctionCallFromLLM
-
-# Suppress gRPC fork warnings
-os.environ["GRPC_ENABLE_FORK_SUPPORT"] = "false"
-
-from loguru import logger
-
-from pipecat.frames.frames import LLMTextFrame
-from pipecat.metrics.metrics import LLMTokenUsage
-from pipecat.processors.aggregators.openai_llm_context import OpenAILLMContext
-from pipecat.services.openai.base_llm import BaseOpenAILLMService
-from pipecat.services.openai.llm import OpenAILLMService
-
-
-@dataclass
-class GoogleOpenAILLMSettings(BaseOpenAILLMService.Settings):
- """Settings for GoogleLLMOpenAIBetaService."""
-
- pass
-
-
-class GoogleLLMOpenAIBetaService(OpenAILLMService):
- """Google LLM service using OpenAI-compatible API format.
-
- This service provides access to Google's AI LLM models (like Gemini) through
- the OpenAI API format. It handles streaming responses, function calls, and
- tool usage while maintaining compatibility with OpenAI's interface.
-
- Note: This service includes a workaround for a Google API bug where function
- call indices may be incorrectly set to None, resulting in empty function names.
-
- .. deprecated:: 0.0.82
- GoogleLLMOpenAIBetaService is deprecated and will be removed in a future version.
- Use GoogleLLMService instead for better integration with Google's native API.
-
- Reference:
- https://ai.google.dev/gemini-api/docs/openai
- """
-
- Settings = GoogleOpenAILLMSettings
- _settings: Settings
-
- def __init__(
- self,
- *,
- api_key: str,
- base_url: str = "https://generativelanguage.googleapis.com/v1beta/openai/",
- model: Optional[str] = None,
- settings: Optional[Settings] = None,
- **kwargs,
- ):
- """Initialize the Google LLM service.
-
- Args:
- api_key: Google API key for authentication.
- base_url: Base URL for Google's OpenAI-compatible API.
- model: Google model name to use (e.g., "gemini-2.0-flash").
-
- .. deprecated:: 0.0.105
- Use ``settings=GoogleLLMOpenAIBetaService.Settings(model=...)`` instead.
-
- settings: Runtime-updatable settings. When provided alongside deprecated
- parameters, ``settings`` values take precedence.
- **kwargs: Additional arguments passed to the parent OpenAILLMService.
- """
- import warnings
-
- with warnings.catch_warnings():
- warnings.simplefilter("always")
- warnings.warn(
- "GoogleLLMOpenAIBetaService is deprecated and will be removed in a future version. "
- "Use GoogleLLMService instead for better integration with Google's native API.",
- DeprecationWarning,
- stacklevel=2,
- )
-
- # 1. Initialize default_settings with hardcoded defaults
- default_settings = self.Settings(model="gemini-2.0-flash")
-
- # 2. Apply direct init arg overrides (deprecated)
- if model is not None:
- self._warn_init_param_moved_to_settings("model", "model")
- default_settings.model = model
-
- # 3. (No step 3, as there's no params object to apply)
-
- # 4. Apply settings delta (canonical API, always wins)
- if settings is not None:
- default_settings.apply_update(settings)
-
- super().__init__(api_key=api_key, base_url=base_url, settings=default_settings, **kwargs)
-
- async def _process_context(self, context: OpenAILLMContext):
- functions_list = []
- arguments_list = []
- tool_id_list = []
- func_idx = 0
- function_name = ""
- arguments = ""
- tool_call_id = ""
-
- await self.start_ttfb_metrics()
-
- chunk_stream: AsyncStream[
- ChatCompletionChunk
- ] = await self._stream_chat_completions_specific_context(context)
-
- # Use context manager to ensure stream is closed on cancellation/exception.
- # Without this, CancelledError during iteration leaves the underlying socket open.
- async with chunk_stream:
- async for chunk in chunk_stream:
- if chunk.usage:
- tokens = LLMTokenUsage(
- prompt_tokens=chunk.usage.prompt_tokens or 0,
- completion_tokens=chunk.usage.completion_tokens or 0,
- total_tokens=chunk.usage.total_tokens or 0,
- )
- await self.start_llm_usage_metrics(tokens)
-
- if chunk.choices is None or len(chunk.choices) == 0:
- continue
-
- await self.stop_ttfb_metrics()
-
- if not chunk.choices[0].delta:
- continue
-
- if chunk.choices[0].delta.tool_calls:
- # We're streaming the LLM response to enable the fastest response times.
- # For text, we just yield each chunk as we receive it and count on consumers
- # to do whatever coalescing they need (eg. to pass full sentences to TTS)
- #
- # If the LLM is a function call, we'll do some coalescing here.
- # If the response contains a function name, we'll yield a frame to tell consumers
- # that they can start preparing to call the function with that name.
- # We accumulate all the arguments for the rest of the streamed response, then when
- # the response is done, we package up all the arguments and the function name and
- # yield a frame containing the function name and the arguments.
- logger.debug(f"Tool call: {chunk.choices[0].delta.tool_calls}")
- tool_call = chunk.choices[0].delta.tool_calls[0]
- if tool_call.index != func_idx:
- functions_list.append(function_name)
- arguments_list.append(arguments)
- tool_id_list.append(tool_call_id)
- function_name = ""
- arguments = ""
- tool_call_id = ""
- func_idx += 1
- if tool_call.function and tool_call.function.name:
- function_name += tool_call.function.name
- tool_call_id = tool_call.id
- if tool_call.function and tool_call.function.arguments:
- # Keep iterating through the response to collect all the argument fragments
- arguments += tool_call.function.arguments
- elif chunk.choices[0].delta.content:
- await self.push_frame(LLMTextFrame(chunk.choices[0].delta.content))
-
- # if we got a function name and arguments, check to see if it's a function with
- # a registered handler. If so, run the registered callback, save the result to
- # the context, and re-prompt to get a chat answer. If we don't have a registered
- # handler, raise an exception.
- if function_name and arguments:
- # added to the list as last function name and arguments not added to the list
- functions_list.append(function_name)
- arguments_list.append(arguments)
- tool_id_list.append(tool_call_id)
-
- logger.debug(
- f"Function list: {functions_list}, Arguments list: {arguments_list}, Tool ID list: {tool_id_list}"
- )
-
- function_calls = []
- for function_name, arguments, tool_id in zip(
- functions_list, arguments_list, tool_id_list
- ):
- if function_name == "":
- # TODO: Remove the _process_context method once Google resolves the bug
- # where the index is incorrectly set to None instead of returning the actual index,
- # which currently results in an empty function name('').
- continue
-
- try:
- arguments = json.loads(arguments)
- except json.JSONDecodeError:
- logger.warning(f"{self}: Failed to parse function call arguments: {arguments}")
- continue
-
- function_calls.append(
- FunctionCallFromLLM(
- context=context,
- tool_call_id=tool_id,
- function_name=function_name,
- arguments=arguments,
- )
- )
-
- await self.run_function_calls(function_calls)
diff --git a/src/pipecat/services/grok/llm.py b/src/pipecat/services/grok/llm.py
index e81db5458..cddaa7d4f 100644
--- a/src/pipecat/services/grok/llm.py
+++ b/src/pipecat/services/grok/llm.py
@@ -6,7 +6,7 @@
"""Grok LLM service implementation.
-.. deprecated::
+.. deprecated:: 0.0.108
This module is deprecated. Please use GrokLLMService from
pipecat.services.xai.llm instead.
"""
diff --git a/src/pipecat/services/grok/realtime/events.py b/src/pipecat/services/grok/realtime/events.py
index 546308e26..554ab0068 100644
--- a/src/pipecat/services/grok/realtime/events.py
+++ b/src/pipecat/services/grok/realtime/events.py
@@ -6,7 +6,7 @@
"""Grok Realtime event models.
-.. deprecated::
+.. deprecated:: 0.0.108
This module is deprecated. Please use pipecat.services.xai.realtime.events instead.
"""
diff --git a/src/pipecat/services/grok/realtime/llm.py b/src/pipecat/services/grok/realtime/llm.py
index 5d35e158f..5373ae757 100644
--- a/src/pipecat/services/grok/realtime/llm.py
+++ b/src/pipecat/services/grok/realtime/llm.py
@@ -6,7 +6,7 @@
"""Grok Realtime LLM service.
-.. deprecated::
+.. deprecated:: 0.0.108
This module is deprecated. Please use GrokRealtimeLLMService from
pipecat.services.xai.realtime.llm instead.
"""
diff --git a/src/pipecat/services/nim/__init__.py b/src/pipecat/services/nim/__init__.py
deleted file mode 100644
index a885e6fa3..000000000
--- a/src/pipecat/services/nim/__init__.py
+++ /dev/null
@@ -1,13 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
-
-import sys
-
-from pipecat.services import DeprecatedModuleProxy
-
-from .llm import *
-
-sys.modules[__name__] = DeprecatedModuleProxy(globals(), "nim", "nim.llm")
diff --git a/src/pipecat/services/nim/llm.py b/src/pipecat/services/nim/llm.py
deleted file mode 100644
index 360073c4e..000000000
--- a/src/pipecat/services/nim/llm.py
+++ /dev/null
@@ -1,30 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
-
-"""NVIDIA NIM API service implementation.
-
-This module provides a service for interacting with NVIDIA's NIM (NVIDIA Inference
-Microservice) API while maintaining compatibility with the OpenAI-style interface.
-
-.. deprecated:: 0.0.96
- This module is deprecated. Please NvidiaLLMService from
- pipecat.services.nvidia.llm instead.
-"""
-
-import warnings
-
-from pipecat.services.nvidia.llm import NvidiaLLMService
-
-with warnings.catch_warnings():
- warnings.simplefilter("always")
- warnings.warn(
- "NimLLMService from pipecat.services.nim.llm is deprecated. "
- "Please use NvidiaLLMService from pipecat.services.nvidia.llm instead.",
- DeprecationWarning,
- stacklevel=2,
- )
-
-NimLLMService = NvidiaLLMService
diff --git a/src/pipecat/services/openai_realtime/__init__.py b/src/pipecat/services/openai_realtime/__init__.py
deleted file mode 100644
index 90729ef31..000000000
--- a/src/pipecat/services/openai_realtime/__init__.py
+++ /dev/null
@@ -1,37 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
-
-import warnings
-
-from pipecat.services.azure.realtime.llm import AzureRealtimeLLMService
-from pipecat.services.openai.realtime.events import (
- InputAudioNoiseReduction,
- InputAudioTranscription,
- SemanticTurnDetection,
- SessionProperties,
- TurnDetection,
-)
-from pipecat.services.openai.realtime.llm import OpenAIRealtimeLLMService
-
-with warnings.catch_warnings():
- warnings.simplefilter("always")
- warnings.warn(
- "Types in pipecat.services.openai_realtime are deprecated. "
- "Please use the equivalent types from "
- "pipecat.services.openai.realtime instead.",
- DeprecationWarning,
- stacklevel=2,
- )
-
-__all__ = [
- "AzureRealtimeLLMService",
- "InputAudioNoiseReduction",
- "InputAudioTranscription",
- "SemanticTurnDetection",
- "SessionProperties",
- "TurnDetection",
- "OpenAIRealtimeLLMService",
-]
diff --git a/src/pipecat/services/openai_realtime/azure.py b/src/pipecat/services/openai_realtime/azure.py
deleted file mode 100644
index 76a2739bb..000000000
--- a/src/pipecat/services/openai_realtime/azure.py
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
-
-"""Azure OpenAI Realtime LLM service implementation."""
-
-import warnings
-
-from pipecat.services.azure.realtime.llm import *
-
-with warnings.catch_warnings():
- warnings.simplefilter("always")
- warnings.warn(
- "Types in pipecat.services.openai_realtime.azure are deprecated. "
- "Please use the equivalent types from "
- "pipecat.services.azure.realtime.llm instead.",
- DeprecationWarning,
- stacklevel=2,
- )
diff --git a/src/pipecat/services/openai_realtime/context.py b/src/pipecat/services/openai_realtime/context.py
deleted file mode 100644
index 75dd6c216..000000000
--- a/src/pipecat/services/openai_realtime/context.py
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
-
-"""OpenAI Realtime LLM context and aggregator implementations.
-
-.. deprecated:: 0.0.91
- OpenAI Realtime no longer uses types from this module under the hood.
- It now uses `LLMContext` and `LLMContextAggregatorPair`.
- Using the new patterns should allow you to not need types from this module.
-
- See deprecation warning in pipecat.services.openai.realtime.context for
- more details.
-"""
-
-from pipecat.services.openai.realtime.context import *
diff --git a/src/pipecat/services/openai_realtime/events.py b/src/pipecat/services/openai_realtime/events.py
deleted file mode 100644
index bbbbca271..000000000
--- a/src/pipecat/services/openai_realtime/events.py
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
-
-"""Event models and data structures for OpenAI Realtime API communication."""
-
-import warnings
-
-from pipecat.services.openai.realtime.events import *
-
-with warnings.catch_warnings():
- warnings.simplefilter("always")
- warnings.warn(
- "Types in pipecat.services.openai_realtime.events are deprecated. "
- "Please use the equivalent types from "
- "pipecat.services.openai.realtime.events instead.",
- DeprecationWarning,
- stacklevel=2,
- )
diff --git a/src/pipecat/services/openai_realtime/frames.py b/src/pipecat/services/openai_realtime/frames.py
deleted file mode 100644
index c2db1eb70..000000000
--- a/src/pipecat/services/openai_realtime/frames.py
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
-
-"""Custom frame types for OpenAI Realtime API integration."""
-
-import warnings
-
-from pipecat.services.openai.realtime.frames import *
-
-with warnings.catch_warnings():
- warnings.simplefilter("always")
- warnings.warn(
- "Types in pipecat.services.openai_realtime.frames are deprecated. "
- "Please use the equivalent types from "
- "pipecat.services.openai.realtime.frames instead.",
- DeprecationWarning,
- stacklevel=2,
- )
diff --git a/src/pipecat/services/openai_realtime_beta/__init__.py b/src/pipecat/services/openai_realtime_beta/__init__.py
deleted file mode 100644
index b7c976bb6..000000000
--- a/src/pipecat/services/openai_realtime_beta/__init__.py
+++ /dev/null
@@ -1,19 +0,0 @@
-from .azure import AzureRealtimeBetaLLMService
-from .events import (
- InputAudioNoiseReduction,
- InputAudioTranscription,
- SemanticTurnDetection,
- SessionProperties,
- TurnDetection,
-)
-from .openai import OpenAIRealtimeBetaLLMService
-
-__all__ = [
- "AzureRealtimeBetaLLMService",
- "InputAudioNoiseReduction",
- "InputAudioTranscription",
- "SemanticTurnDetection",
- "SessionProperties",
- "TurnDetection",
- "OpenAIRealtimeBetaLLMService",
-]
diff --git a/src/pipecat/services/openai_realtime_beta/azure.py b/src/pipecat/services/openai_realtime_beta/azure.py
deleted file mode 100644
index b590f2c29..000000000
--- a/src/pipecat/services/openai_realtime_beta/azure.py
+++ /dev/null
@@ -1,94 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
-
-"""Azure OpenAI Realtime Beta LLM service implementation."""
-
-import warnings
-from dataclasses import dataclass
-
-from loguru import logger
-
-from .openai import OpenAIRealtimeBetaLLMService
-
-try:
- from websockets.asyncio.client import connect as websocket_connect
-except ModuleNotFoundError as e:
- logger.error(f"Exception: {e}")
- logger.error(
- "In order to use OpenAI, you need to `pip install pipecat-ai[openai]`. Also, set `OPENAI_API_KEY` environment variable."
- )
- raise Exception(f"Missing module: {e}")
-
-
-@dataclass
-class AzureRealtimeBetaLLMSettings(OpenAIRealtimeBetaLLMService.Settings):
- """Settings for AzureRealtimeBetaLLMService."""
-
- pass
-
-
-class AzureRealtimeBetaLLMService(OpenAIRealtimeBetaLLMService):
- """Azure OpenAI Realtime Beta LLM service with Azure-specific authentication.
-
- .. deprecated:: 0.0.84
- `AzureRealtimeBetaLLMService` is deprecated, use `AzureRealtimeLLMService` instead.
- This class will be removed in version 1.0.0.
-
- Extends the OpenAI Realtime service to work with Azure OpenAI endpoints,
- using Azure's authentication headers and endpoint format. Provides the same
- real-time audio and text communication capabilities as the base OpenAI service.
- """
-
- Settings = AzureRealtimeBetaLLMSettings
- _settings: Settings
-
- def __init__(
- self,
- *,
- api_key: str,
- base_url: str,
- **kwargs,
- ):
- """Initialize Azure Realtime Beta LLM service.
-
- Args:
- api_key: The API key for the Azure OpenAI service.
- base_url: The full Azure WebSocket endpoint URL including api-version and deployment.
- Example: "wss://my-project.openai.azure.com/openai/realtime?api-version=2024-10-01-preview&deployment=my-realtime-deployment"
- **kwargs: Additional arguments passed to parent OpenAIRealtimeBetaLLMService.
- """
- super().__init__(base_url=base_url, api_key=api_key, **kwargs)
-
- with warnings.catch_warnings():
- warnings.simplefilter("always")
- warnings.warn(
- "AzureRealtimeBetaLLMService is deprecated and will be removed in version 1.0.0. "
- "Use AzureRealtimeLLMService instead.",
- DeprecationWarning,
- stacklevel=2,
- )
-
- self.api_key = api_key
- self.base_url = base_url
-
- async def _connect(self):
- try:
- if self._websocket:
- # Here we assume that if we have a websocket, we are connected. We
- # handle disconnections in the send/recv code paths.
- return
-
- logger.info(f"Connecting to {self.base_url}")
- self._websocket = await websocket_connect(
- uri=self.base_url,
- additional_headers={
- "api-key": self.api_key,
- },
- )
- self._receive_task = self.create_task(self._receive_task_handler())
- except Exception as e:
- await self.push_error(error_msg=f"Error connecting: {e}", exception=e)
- self._websocket = None
diff --git a/src/pipecat/services/openai_realtime_beta/context.py b/src/pipecat/services/openai_realtime_beta/context.py
deleted file mode 100644
index a1bbd6c92..000000000
--- a/src/pipecat/services/openai_realtime_beta/context.py
+++ /dev/null
@@ -1,272 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
-
-"""OpenAI Realtime LLM context and aggregator implementations."""
-
-import copy
-import json
-
-from loguru import logger
-
-from pipecat.frames.frames import (
- Frame,
- FunctionCallResultFrame,
- InterimTranscriptionFrame,
- LLMMessagesUpdateFrame,
- LLMSetToolsFrame,
- LLMTextFrame,
- TranscriptionFrame,
-)
-from pipecat.processors.aggregators.openai_llm_context import OpenAILLMContext
-from pipecat.processors.frame_processor import FrameDirection
-from pipecat.services.openai.llm import (
- OpenAIAssistantContextAggregator,
- OpenAIUserContextAggregator,
-)
-
-from . import events
-from .frames import RealtimeFunctionCallResultFrame, RealtimeMessagesUpdateFrame
-
-
-class OpenAIRealtimeLLMContext(OpenAILLMContext):
- """OpenAI Realtime LLM context with session management and message conversion.
-
- Extends the standard OpenAI LLM context to support real-time session properties,
- instruction management, and conversion between standard message formats and
- realtime conversation items.
- """
-
- def __init__(self, messages=None, tools=None, **kwargs):
- """Initialize the OpenAIRealtimeLLMContext.
-
- Args:
- messages: Initial conversation messages. Defaults to None.
- tools: Available function tools. Defaults to None.
- **kwargs: Additional arguments passed to parent OpenAILLMContext.
- """
- super().__init__(messages=messages, tools=tools, **kwargs)
- self.__setup_local()
-
- def __setup_local(self):
- self.llm_needs_settings_update = True
- self.llm_needs_initial_messages = True
- self._session_instructions = ""
-
- return
-
- @staticmethod
- def upgrade_to_realtime(obj: OpenAILLMContext) -> "OpenAIRealtimeLLMContext":
- """Upgrade a standard OpenAI LLM context to a realtime context.
-
- Args:
- obj: The OpenAILLMContext instance to upgrade.
-
- Returns:
- The upgraded OpenAIRealtimeLLMContext instance.
- """
- if isinstance(obj, OpenAILLMContext) and not isinstance(obj, OpenAIRealtimeLLMContext):
- obj.__class__ = OpenAIRealtimeLLMContext
- obj.__setup_local()
- return obj
-
- # todo
- # - finish implementing all frames
-
- def from_standard_message(self, message):
- """Convert a standard message format to a realtime conversation item.
-
- Args:
- message: The standard message dictionary to convert.
-
- Returns:
- A ConversationItem instance for the realtime API.
- """
- if message.get("role") == "user":
- content = message.get("content")
- if isinstance(message.get("content"), list):
- content = ""
- for c in message.get("content"):
- if c.get("type") == "text":
- content += " " + c.get("text")
- else:
- logger.error(
- f"Unhandled content type in context message: {c.get('type')} - {message}"
- )
- return events.ConversationItem(
- role="user",
- type="message",
- content=[events.ItemContent(type="input_text", text=content)],
- )
- if message.get("role") == "assistant" and message.get("tool_calls"):
- tc = message.get("tool_calls")[0]
- return events.ConversationItem(
- type="function_call",
- call_id=tc["id"],
- name=tc["function"]["name"],
- arguments=tc["function"]["arguments"],
- )
- logger.error(f"Unhandled message type in from_standard_message: {message}")
-
- def get_messages_for_initializing_history(self):
- """Get conversation items for initializing the realtime session history.
-
- Converts the context's messages to a format suitable for the realtime API,
- handling system instructions and conversation history packaging.
-
- Returns:
- List of conversation items for session initialization.
- """
- # We can't load a long conversation history into the openai realtime api yet. (The API/model
- # forgets that it can do audio, if you do a series of `conversation.item.create` calls.) So
- # our general strategy until this is fixed is just to put everything into a first "user"
- # message as a single input.
- if not self.messages:
- return []
-
- messages = copy.deepcopy(self.messages)
-
- # If we have a "system" message as our first message, let's pull that out into session
- # "instructions"
- if messages[0].get("role") == "system":
- self.llm_needs_settings_update = True
- system = messages.pop(0)
- content = system.get("content")
- if isinstance(content, str):
- self._session_instructions = content
- elif isinstance(content, list):
- self._session_instructions = content[0].get("text")
- if not messages:
- return []
-
- # If we have just a single "user" item, we can just send it normally
- if len(messages) == 1 and messages[0].get("role") == "user":
- return [self.from_standard_message(messages[0])]
-
- # Otherwise, let's pack everything into a single "user" message with a bit of
- # explanation for the LLM
- intro_text = """
- This is a previously saved conversation. Please treat this conversation history as a
- starting point for the current conversation."""
-
- trailing_text = """
- This is the end of the previously saved conversation. Please continue the conversation
- from here. If the last message is a user instruction or question, act on that instruction
- or answer the question. If the last message is an assistant response, simple say that you
- are ready to continue the conversation."""
-
- return [
- {
- "role": "user",
- "type": "message",
- "content": [
- {
- "type": "input_text",
- "text": "\n\n".join(
- [intro_text, json.dumps(messages, indent=2), trailing_text]
- ),
- }
- ],
- }
- ]
-
- def add_user_content_item_as_message(self, item):
- """Add a user content item as a standard message to the context.
-
- Args:
- item: The conversation item to add as a user message.
- """
- message = {
- "role": "user",
- "content": [{"type": "text", "text": item.content[0].transcript}],
- }
- self.add_message(message)
-
-
-class OpenAIRealtimeUserContextAggregator(OpenAIUserContextAggregator):
- """User context aggregator for OpenAI Realtime API.
-
- Handles user input frames and generates appropriate context updates
- for the realtime conversation, including message updates and tool settings.
-
- Args:
- context: The OpenAI realtime LLM context.
- **kwargs: Additional arguments passed to parent aggregator.
- """
-
- async def process_frame(
- self, frame: Frame, direction: FrameDirection = FrameDirection.DOWNSTREAM
- ):
- """Process incoming frames and handle realtime-specific frame types.
-
- Args:
- frame: The frame to process.
- direction: The direction of frame flow in the pipeline.
- """
- await super().process_frame(frame, direction)
- # Parent does not push LLMMessagesUpdateFrame. This ensures that in a typical pipeline,
- # messages are only processed by the user context aggregator, which is generally what we want. But
- # we also need to send new messages over the websocket, so the openai realtime API has them
- # in its context.
- if isinstance(frame, LLMMessagesUpdateFrame):
- await self.push_frame(RealtimeMessagesUpdateFrame(context=self._context))
-
- # Parent also doesn't push the LLMSetToolsFrame.
- if isinstance(frame, LLMSetToolsFrame):
- await self.push_frame(frame, direction)
-
- async def push_aggregation(self):
- """Push user input aggregation.
-
- Currently ignores all user input coming into the pipeline as realtime
- audio input is handled directly by the service.
- """
- # for the moment, ignore all user input coming into the pipeline.
- # todo: think about whether/how to fix this to allow for text input from
- # upstream (transport/transcription, or other sources)
- pass
-
-
-class OpenAIRealtimeAssistantContextAggregator(OpenAIAssistantContextAggregator):
- """Assistant context aggregator for OpenAI Realtime API.
-
- Handles assistant output frames from the realtime service, filtering
- out duplicate text frames and managing function call results.
-
- Args:
- context: The OpenAI realtime LLM context.
- **kwargs: Additional arguments passed to parent aggregator.
- """
-
- # The LLMAssistantContextAggregator uses TextFrames to aggregate the LLM output,
- # but the OpenAIRealtimeLLMService pushes LLMTextFrames and TTSTextFrames. We
- # need to override this proces_frame for LLMTextFrame, so that only the TTSTextFrames
- # are process. This ensures that the context gets only one set of messages.
- # OpenAIRealtimeLLMService also pushes TranscriptionFrames and InterimTranscriptionFrames,
- # so we need to ignore pushing those as well, as they're also TextFrames.
- async def process_frame(self, frame: Frame, direction: FrameDirection):
- """Process assistant frames, filtering out duplicate text content.
-
- Args:
- frame: The frame to process.
- direction: The direction of frame flow in the pipeline.
- """
- if not isinstance(frame, (LLMTextFrame, TranscriptionFrame, InterimTranscriptionFrame)):
- await super().process_frame(frame, direction)
-
- async def handle_function_call_result(self, frame: FunctionCallResultFrame):
- """Handle function call result and notify the realtime service.
-
- Args:
- frame: The function call result frame to handle.
- """
- await super().handle_function_call_result(frame)
-
- # The standard function callback code path pushes the FunctionCallResultFrame from the llm itself,
- # so we didn't have a chance to add the result to the openai realtime api context. Let's push a
- # special frame to do that.
- await self.push_frame(
- RealtimeFunctionCallResultFrame(result_frame=frame), FrameDirection.UPSTREAM
- )
diff --git a/src/pipecat/services/openai_realtime_beta/events.py b/src/pipecat/services/openai_realtime_beta/events.py
deleted file mode 100644
index 596a11a3b..000000000
--- a/src/pipecat/services/openai_realtime_beta/events.py
+++ /dev/null
@@ -1,978 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
-
-"""Event models and data structures for OpenAI Realtime API communication."""
-
-import json
-import uuid
-from typing import Any, Dict, List, Literal, Optional, Union
-
-from pydantic import BaseModel, ConfigDict, Field
-
-#
-# session properties
-#
-
-
-class InputAudioTranscription(BaseModel):
- """Configuration for audio transcription settings."""
-
- model: str = "gpt-4o-transcribe"
- language: Optional[str]
- prompt: Optional[str]
-
- def __init__(
- self,
- model: Optional[str] = "gpt-4o-transcribe",
- language: Optional[str] = None,
- prompt: Optional[str] = None,
- ):
- """Initialize InputAudioTranscription.
-
- Args:
- model: Transcription model to use (e.g., "gpt-4o-transcribe", "whisper-1").
- language: Optional language code for transcription.
- prompt: Optional transcription hint text.
- """
- super().__init__(model=model, language=language, prompt=prompt)
-
-
-class TurnDetection(BaseModel):
- """Server-side voice activity detection configuration.
-
- Parameters:
- type: Detection type, must be "server_vad".
- threshold: Voice activity detection threshold (0.0-1.0). Defaults to 0.5.
- prefix_padding_ms: Padding before speech starts in milliseconds. Defaults to 300.
- silence_duration_ms: Silence duration to detect speech end in milliseconds. Defaults to 800.
- """
-
- type: Optional[Literal["server_vad"]] = "server_vad"
- threshold: Optional[float] = 0.5
- prefix_padding_ms: Optional[int] = 300
- silence_duration_ms: Optional[int] = 800
-
-
-class SemanticTurnDetection(BaseModel):
- """Semantic-based turn detection configuration.
-
- Parameters:
- type: Detection type, must be "semantic_vad".
- eagerness: Turn detection eagerness level. Can be "low", "medium", "high", or "auto".
- create_response: Whether to automatically create responses on turn detection.
- interrupt_response: Whether to interrupt ongoing responses on turn detection.
- """
-
- type: Optional[Literal["semantic_vad"]] = "semantic_vad"
- eagerness: Optional[Literal["low", "medium", "high", "auto"]] = None
- create_response: Optional[bool] = None
- interrupt_response: Optional[bool] = None
-
-
-class InputAudioNoiseReduction(BaseModel):
- """Input audio noise reduction configuration.
-
- Parameters:
- type: Noise reduction type for different microphone scenarios.
- """
-
- type: Optional[Literal["near_field", "far_field"]]
-
-
-class SessionProperties(BaseModel):
- """Configuration properties for an OpenAI Realtime session.
-
- Parameters:
- modalities: Communication modalities to enable (text, audio, or both).
- instructions: System instructions for the assistant.
- voice: Voice ID for text-to-speech output.
- input_audio_format: Format for input audio data.
- output_audio_format: Format for output audio data.
- input_audio_transcription: Configuration for input audio transcription.
- input_audio_noise_reduction: Configuration for input audio noise reduction.
- turn_detection: Turn detection configuration or False to disable.
- tools: Available function tools for the assistant.
- tool_choice: Tool usage strategy ("auto", "none", or "required").
- temperature: Sampling temperature for response generation.
- max_response_output_tokens: Maximum tokens in response or "inf" for unlimited.
- """
-
- modalities: Optional[List[Literal["text", "audio"]]] = None
- instructions: Optional[str] = None
- voice: Optional[str] = None
- input_audio_format: Optional[Literal["pcm16", "g711_ulaw", "g711_alaw"]] = None
- output_audio_format: Optional[Literal["pcm16", "g711_ulaw", "g711_alaw"]] = None
- input_audio_transcription: Optional[InputAudioTranscription] = None
- input_audio_noise_reduction: Optional[InputAudioNoiseReduction] = None
- # set turn_detection to False to disable turn detection
- turn_detection: Optional[Union[TurnDetection, SemanticTurnDetection, bool]] = Field(
- default=None
- )
- tools: Optional[List[Dict]] = None
- tool_choice: Optional[Literal["auto", "none", "required"]] = None
- temperature: Optional[float] = None
- max_response_output_tokens: Optional[Union[int, Literal["inf"]]] = None
-
-
-#
-# context
-#
-
-
-class ItemContent(BaseModel):
- """Content within a conversation item.
-
- Parameters:
- type: Content type (text, audio, input_text, or input_audio).
- text: Text content for text-based items.
- audio: Base64-encoded audio data for audio items.
- transcript: Transcribed text for audio items.
- """
-
- type: Literal["text", "audio", "input_text", "input_audio"]
- text: Optional[str] = None
- audio: Optional[str] = None # base64-encoded audio
- transcript: Optional[str] = None
-
-
-class ConversationItem(BaseModel):
- """A conversation item in the realtime session.
-
- Parameters:
- id: Unique identifier for the item, auto-generated if not provided.
- object: Object type identifier for the realtime API.
- type: Item type (message, function_call, or function_call_output).
- status: Current status of the item.
- role: Speaker role for message items (user, assistant, or system).
- content: Content list for message items.
- call_id: Function call identifier for function_call items.
- name: Function name for function_call items.
- arguments: Function arguments as JSON string for function_call items.
- output: Function output as JSON string for function_call_output items.
- """
-
- id: str = Field(default_factory=lambda: str(uuid.uuid4().hex))
- object: Optional[Literal["realtime.item"]] = None
- type: Literal["message", "function_call", "function_call_output"]
- status: Optional[Literal["completed", "in_progress", "incomplete"]] = None
- # role and content are present for message items
- role: Optional[Literal["user", "assistant", "system"]] = None
- content: Optional[List[ItemContent]] = None
- # these four fields are present for function_call items
- call_id: Optional[str] = None
- name: Optional[str] = None
- arguments: Optional[str] = None
- output: Optional[str] = None
-
-
-class RealtimeConversation(BaseModel):
- """A realtime conversation session.
-
- Parameters:
- id: Unique identifier for the conversation.
- object: Object type identifier, always "realtime.conversation".
- """
-
- id: str
- object: Literal["realtime.conversation"]
-
-
-class ResponseProperties(BaseModel):
- """Properties for configuring assistant responses.
-
- Parameters:
- modalities: Output modalities for the response. Defaults to ["audio", "text"].
- instructions: Specific instructions for this response.
- voice: Voice ID for text-to-speech in this response.
- output_audio_format: Audio format for this response.
- tools: Available tools for this response.
- tool_choice: Tool usage strategy for this response.
- temperature: Sampling temperature for this response.
- max_response_output_tokens: Maximum tokens for this response.
- """
-
- modalities: Optional[List[Literal["text", "audio"]]] = ["audio", "text"]
- instructions: Optional[str] = None
- voice: Optional[str] = None
- output_audio_format: Optional[Literal["pcm16", "g711_ulaw", "g711_alaw"]] = None
- tools: Optional[List[Dict]] = Field(default_factory=list)
- tool_choice: Optional[Literal["auto", "none", "required"]] = None
- temperature: Optional[float] = None
- max_response_output_tokens: Optional[Union[int, Literal["inf"]]] = None
-
-
-#
-# error class
-#
-class RealtimeError(BaseModel):
- """Error information from the realtime API.
-
- Parameters:
- type: Error type identifier.
- code: Specific error code.
- message: Human-readable error message.
- param: Parameter name that caused the error, if applicable.
- event_id: Event ID associated with the error, if applicable.
- """
-
- type: str
- code: Optional[str] = ""
- message: str
- param: Optional[str] = None
- event_id: Optional[str] = None
-
-
-#
-# client events
-#
-
-
-class ClientEvent(BaseModel):
- """Base class for client events sent to the realtime API.
-
- Parameters:
- event_id: Unique identifier for the event, auto-generated if not provided.
- """
-
- event_id: str = Field(default_factory=lambda: str(uuid.uuid4()))
-
-
-class SessionUpdateEvent(ClientEvent):
- """Event to update session properties.
-
- Parameters:
- type: Event type, always "session.update".
- session: Updated session properties.
- """
-
- type: Literal["session.update"] = "session.update"
- session: SessionProperties
-
- def model_dump(self, *args, **kwargs) -> Dict[str, Any]:
- """Serialize the event to a dictionary.
-
- Handles special serialization for turn_detection where False becomes null.
-
- Args:
- *args: Positional arguments passed to parent model_dump.
- **kwargs: Keyword arguments passed to parent model_dump.
-
- Returns:
- Dictionary representation of the event.
- """
- dump = super().model_dump(*args, **kwargs)
-
- # Handle turn_detection so that False is serialized as null
- if "turn_detection" in dump["session"]:
- if dump["session"]["turn_detection"] is False:
- dump["session"]["turn_detection"] = None
-
- return dump
-
-
-class InputAudioBufferAppendEvent(ClientEvent):
- """Event to append audio data to the input buffer.
-
- Parameters:
- type: Event type, always "input_audio_buffer.append".
- audio: Base64-encoded audio data to append.
- """
-
- type: Literal["input_audio_buffer.append"] = "input_audio_buffer.append"
- audio: str # base64-encoded audio
-
-
-class InputAudioBufferCommitEvent(ClientEvent):
- """Event to commit the current input audio buffer.
-
- Parameters:
- type: Event type, always "input_audio_buffer.commit".
- """
-
- type: Literal["input_audio_buffer.commit"] = "input_audio_buffer.commit"
-
-
-class InputAudioBufferClearEvent(ClientEvent):
- """Event to clear the input audio buffer.
-
- Parameters:
- type: Event type, always "input_audio_buffer.clear".
- """
-
- type: Literal["input_audio_buffer.clear"] = "input_audio_buffer.clear"
-
-
-class ConversationItemCreateEvent(ClientEvent):
- """Event to create a new conversation item.
-
- Parameters:
- type: Event type, always "conversation.item.create".
- previous_item_id: ID of the item to insert after, if any.
- item: The conversation item to create.
- """
-
- type: Literal["conversation.item.create"] = "conversation.item.create"
- previous_item_id: Optional[str] = None
- item: ConversationItem
-
-
-class ConversationItemTruncateEvent(ClientEvent):
- """Event to truncate a conversation item's audio content.
-
- Parameters:
- type: Event type, always "conversation.item.truncate".
- item_id: ID of the item to truncate.
- content_index: Index of the content to truncate within the item.
- audio_end_ms: End time in milliseconds for the truncated audio.
- """
-
- type: Literal["conversation.item.truncate"] = "conversation.item.truncate"
- item_id: str
- content_index: int
- audio_end_ms: int
-
-
-class ConversationItemDeleteEvent(ClientEvent):
- """Event to delete a conversation item.
-
- Parameters:
- type: Event type, always "conversation.item.delete".
- item_id: ID of the item to delete.
- """
-
- type: Literal["conversation.item.delete"] = "conversation.item.delete"
- item_id: str
-
-
-class ConversationItemRetrieveEvent(ClientEvent):
- """Event to retrieve a conversation item by ID.
-
- Parameters:
- type: Event type, always "conversation.item.retrieve".
- item_id: ID of the item to retrieve.
- """
-
- type: Literal["conversation.item.retrieve"] = "conversation.item.retrieve"
- item_id: str
-
-
-class ResponseCreateEvent(ClientEvent):
- """Event to create a new assistant response.
-
- Parameters:
- type: Event type, always "response.create".
- response: Optional response configuration properties.
- """
-
- type: Literal["response.create"] = "response.create"
- response: Optional[ResponseProperties] = None
-
-
-class ResponseCancelEvent(ClientEvent):
- """Event to cancel the current assistant response.
-
- Parameters:
- type: Event type, always "response.cancel".
- """
-
- type: Literal["response.cancel"] = "response.cancel"
-
-
-#
-# server events
-#
-
-
-class ServerEvent(BaseModel):
- """Base class for server events received from the realtime API.
-
- Parameters:
- event_id: Unique identifier for the event.
- type: Type of the server event.
- """
-
- model_config = ConfigDict(arbitrary_types_allowed=True)
-
- event_id: str
- type: str
-
-
-class SessionCreatedEvent(ServerEvent):
- """Event indicating a session has been created.
-
- Parameters:
- type: Event type, always "session.created".
- session: The created session properties.
- """
-
- type: Literal["session.created"]
- session: SessionProperties
-
-
-class SessionUpdatedEvent(ServerEvent):
- """Event indicating a session has been updated.
-
- Parameters:
- type: Event type, always "session.updated".
- session: The updated session properties.
- """
-
- type: Literal["session.updated"]
- session: SessionProperties
-
-
-class ConversationCreated(ServerEvent):
- """Event indicating a conversation has been created.
-
- Parameters:
- type: Event type, always "conversation.created".
- conversation: The created conversation.
- """
-
- type: Literal["conversation.created"]
- conversation: RealtimeConversation
-
-
-class ConversationItemCreated(ServerEvent):
- """Event indicating a conversation item has been created.
-
- Parameters:
- type: Event type, always "conversation.item.created".
- previous_item_id: ID of the previous item, if any.
- item: The created conversation item.
- """
-
- type: Literal["conversation.item.created"]
- previous_item_id: Optional[str] = None
- item: ConversationItem
-
-
-class ConversationItemInputAudioTranscriptionDelta(ServerEvent):
- """Event containing incremental input audio transcription.
-
- Parameters:
- type: Event type, always "conversation.item.input_audio_transcription.delta".
- item_id: ID of the conversation item being transcribed.
- content_index: Index of the content within the item.
- delta: Incremental transcription text.
- """
-
- type: Literal["conversation.item.input_audio_transcription.delta"]
- item_id: str
- content_index: int
- delta: str
-
-
-class ConversationItemInputAudioTranscriptionCompleted(ServerEvent):
- """Event indicating input audio transcription is complete.
-
- Parameters:
- type: Event type, always "conversation.item.input_audio_transcription.completed".
- item_id: ID of the conversation item that was transcribed.
- content_index: Index of the content within the item.
- transcript: Complete transcription text.
- """
-
- type: Literal["conversation.item.input_audio_transcription.completed"]
- item_id: str
- content_index: int
- transcript: str
-
-
-class ConversationItemInputAudioTranscriptionFailed(ServerEvent):
- """Event indicating input audio transcription failed.
-
- Parameters:
- type: Event type, always "conversation.item.input_audio_transcription.failed".
- item_id: ID of the conversation item that failed transcription.
- content_index: Index of the content within the item.
- error: Error details for the transcription failure.
- """
-
- type: Literal["conversation.item.input_audio_transcription.failed"]
- item_id: str
- content_index: int
- error: RealtimeError
-
-
-class ConversationItemTruncated(ServerEvent):
- """Event indicating a conversation item has been truncated.
-
- Parameters:
- type: Event type, always "conversation.item.truncated".
- item_id: ID of the truncated conversation item.
- content_index: Index of the content within the item.
- audio_end_ms: End time in milliseconds for the truncated audio.
- """
-
- type: Literal["conversation.item.truncated"]
- item_id: str
- content_index: int
- audio_end_ms: int
-
-
-class ConversationItemDeleted(ServerEvent):
- """Event indicating a conversation item has been deleted.
-
- Parameters:
- type: Event type, always "conversation.item.deleted".
- item_id: ID of the deleted conversation item.
- """
-
- type: Literal["conversation.item.deleted"]
- item_id: str
-
-
-class ConversationItemRetrieved(ServerEvent):
- """Event containing a retrieved conversation item.
-
- Parameters:
- type: Event type, always "conversation.item.retrieved".
- item: The retrieved conversation item.
- """
-
- type: Literal["conversation.item.retrieved"]
- item: ConversationItem
-
-
-class ResponseCreated(ServerEvent):
- """Event indicating an assistant response has been created.
-
- Parameters:
- type: Event type, always "response.created".
- response: The created response object.
- """
-
- type: Literal["response.created"]
- response: "Response"
-
-
-class ResponseDone(ServerEvent):
- """Event indicating an assistant response is complete.
-
- Parameters:
- type: Event type, always "response.done".
- response: The completed response object.
- """
-
- type: Literal["response.done"]
- response: "Response"
-
-
-class ResponseOutputItemAdded(ServerEvent):
- """Event indicating an output item has been added to a response.
-
- Parameters:
- type: Event type, always "response.output_item.added".
- response_id: ID of the response.
- output_index: Index of the output item.
- item: The added conversation item.
- """
-
- type: Literal["response.output_item.added"]
- response_id: str
- output_index: int
- item: ConversationItem
-
-
-class ResponseOutputItemDone(ServerEvent):
- """Event indicating an output item is complete.
-
- Parameters:
- type: Event type, always "response.output_item.done".
- response_id: ID of the response.
- output_index: Index of the output item.
- item: The completed conversation item.
- """
-
- type: Literal["response.output_item.done"]
- response_id: str
- output_index: int
- item: ConversationItem
-
-
-class ResponseContentPartAdded(ServerEvent):
- """Event indicating a content part has been added to a response.
-
- Parameters:
- type: Event type, always "response.content_part.added".
- response_id: ID of the response.
- item_id: ID of the conversation item.
- output_index: Index of the output item.
- content_index: Index of the content part.
- part: The added content part.
- """
-
- type: Literal["response.content_part.added"]
- response_id: str
- item_id: str
- output_index: int
- content_index: int
- part: ItemContent
-
-
-class ResponseContentPartDone(ServerEvent):
- """Event indicating a content part is complete.
-
- Parameters:
- type: Event type, always "response.content_part.done".
- response_id: ID of the response.
- item_id: ID of the conversation item.
- output_index: Index of the output item.
- content_index: Index of the content part.
- part: The completed content part.
- """
-
- type: Literal["response.content_part.done"]
- response_id: str
- item_id: str
- output_index: int
- content_index: int
- part: ItemContent
-
-
-class ResponseTextDelta(ServerEvent):
- """Event containing incremental text from a response.
-
- Parameters:
- type: Event type, always "response.text.delta".
- response_id: ID of the response.
- item_id: ID of the conversation item.
- output_index: Index of the output item.
- content_index: Index of the content part.
- delta: Incremental text content.
- """
-
- type: Literal["response.text.delta"]
- response_id: str
- item_id: str
- output_index: int
- content_index: int
- delta: str
-
-
-class ResponseTextDone(ServerEvent):
- """Event indicating text content is complete.
-
- Parameters:
- type: Event type, always "response.text.done".
- response_id: ID of the response.
- item_id: ID of the conversation item.
- output_index: Index of the output item.
- content_index: Index of the content part.
- text: Complete text content.
- """
-
- type: Literal["response.text.done"]
- response_id: str
- item_id: str
- output_index: int
- content_index: int
- text: str
-
-
-class ResponseAudioTranscriptDelta(ServerEvent):
- """Event containing incremental audio transcript from a response.
-
- Parameters:
- type: Event type, always "response.audio_transcript.delta".
- response_id: ID of the response.
- item_id: ID of the conversation item.
- output_index: Index of the output item.
- content_index: Index of the content part.
- delta: Incremental transcript text.
- """
-
- type: Literal["response.audio_transcript.delta"]
- response_id: str
- item_id: str
- output_index: int
- content_index: int
- delta: str
-
-
-class ResponseAudioTranscriptDone(ServerEvent):
- """Event indicating audio transcript is complete.
-
- Parameters:
- type: Event type, always "response.audio_transcript.done".
- response_id: ID of the response.
- item_id: ID of the conversation item.
- output_index: Index of the output item.
- content_index: Index of the content part.
- transcript: Complete transcript text.
- """
-
- type: Literal["response.audio_transcript.done"]
- response_id: str
- item_id: str
- output_index: int
- content_index: int
- transcript: str
-
-
-class ResponseAudioDelta(ServerEvent):
- """Event containing incremental audio data from a response.
-
- Parameters:
- type: Event type, always "response.audio.delta".
- response_id: ID of the response.
- item_id: ID of the conversation item.
- output_index: Index of the output item.
- content_index: Index of the content part.
- delta: Base64-encoded incremental audio data.
- """
-
- type: Literal["response.audio.delta"]
- response_id: str
- item_id: str
- output_index: int
- content_index: int
- delta: str # base64-encoded audio
-
-
-class ResponseAudioDone(ServerEvent):
- """Event indicating audio content is complete.
-
- Parameters:
- type: Event type, always "response.audio.done".
- response_id: ID of the response.
- item_id: ID of the conversation item.
- output_index: Index of the output item.
- content_index: Index of the content part.
- """
-
- type: Literal["response.audio.done"]
- response_id: str
- item_id: str
- output_index: int
- content_index: int
-
-
-class ResponseFunctionCallArgumentsDelta(ServerEvent):
- """Event containing incremental function call arguments.
-
- Parameters:
- type: Event type, always "response.function_call_arguments.delta".
- response_id: ID of the response.
- item_id: ID of the conversation item.
- output_index: Index of the output item.
- call_id: ID of the function call.
- delta: Incremental function arguments as JSON.
- """
-
- type: Literal["response.function_call_arguments.delta"]
- response_id: str
- item_id: str
- output_index: int
- call_id: str
- delta: str
-
-
-class ResponseFunctionCallArgumentsDone(ServerEvent):
- """Event indicating function call arguments are complete.
-
- Parameters:
- type: Event type, always "response.function_call_arguments.done".
- response_id: ID of the response.
- item_id: ID of the conversation item.
- output_index: Index of the output item.
- call_id: ID of the function call.
- arguments: Complete function arguments as JSON string.
- """
-
- type: Literal["response.function_call_arguments.done"]
- response_id: str
- item_id: str
- output_index: int
- call_id: str
- arguments: str
-
-
-class InputAudioBufferSpeechStarted(ServerEvent):
- """Event indicating speech has started in the input audio buffer.
-
- Parameters:
- type: Event type, always "input_audio_buffer.speech_started".
- audio_start_ms: Start time of speech in milliseconds.
- item_id: ID of the associated conversation item.
- """
-
- type: Literal["input_audio_buffer.speech_started"]
- audio_start_ms: int
- item_id: str
-
-
-class InputAudioBufferSpeechStopped(ServerEvent):
- """Event indicating speech has stopped in the input audio buffer.
-
- Parameters:
- type: Event type, always "input_audio_buffer.speech_stopped".
- audio_end_ms: End time of speech in milliseconds.
- item_id: ID of the associated conversation item.
- """
-
- type: Literal["input_audio_buffer.speech_stopped"]
- audio_end_ms: int
- item_id: str
-
-
-class InputAudioBufferCommitted(ServerEvent):
- """Event indicating the input audio buffer has been committed.
-
- Parameters:
- type: Event type, always "input_audio_buffer.committed".
- previous_item_id: ID of the previous item, if any.
- item_id: ID of the committed conversation item.
- """
-
- type: Literal["input_audio_buffer.committed"]
- previous_item_id: Optional[str] = None
- item_id: str
-
-
-class InputAudioBufferCleared(ServerEvent):
- """Event indicating the input audio buffer has been cleared.
-
- Parameters:
- type: Event type, always "input_audio_buffer.cleared".
- """
-
- type: Literal["input_audio_buffer.cleared"]
-
-
-class ErrorEvent(ServerEvent):
- """Event indicating an error occurred.
-
- Parameters:
- type: Event type, always "error".
- error: Error details.
- """
-
- type: Literal["error"]
- error: RealtimeError
-
-
-class RateLimitsUpdated(ServerEvent):
- """Event indicating rate limits have been updated.
-
- Parameters:
- type: Event type, always "rate_limits.updated".
- rate_limits: List of rate limit information.
- """
-
- type: Literal["rate_limits.updated"]
- rate_limits: List[Dict[str, Any]]
-
-
-class TokenDetails(BaseModel):
- """Detailed token usage information.
-
- Parameters:
- cached_tokens: Number of cached tokens used. Defaults to 0.
- text_tokens: Number of text tokens used. Defaults to 0.
- audio_tokens: Number of audio tokens used. Defaults to 0.
- """
-
- model_config = ConfigDict(extra="allow")
-
- cached_tokens: Optional[int] = 0
- text_tokens: Optional[int] = 0
- audio_tokens: Optional[int] = 0
-
-
-class Usage(BaseModel):
- """Token usage statistics for a response.
-
- Parameters:
- total_tokens: Total number of tokens used.
- input_tokens: Number of input tokens used.
- output_tokens: Number of output tokens used.
- input_token_details: Detailed breakdown of input token usage.
- output_token_details: Detailed breakdown of output token usage.
- """
-
- total_tokens: int
- input_tokens: int
- output_tokens: int
- input_token_details: TokenDetails
- output_token_details: TokenDetails
-
-
-class Response(BaseModel):
- """A complete assistant response.
-
- Parameters:
- id: Unique identifier for the response.
- object: Object type, always "realtime.response".
- status: Current status of the response.
- status_details: Additional status information.
- output: List of conversation items in the response.
- usage: Token usage statistics for the response.
- """
-
- id: str
- object: Literal["realtime.response"]
- status: Literal["completed", "in_progress", "incomplete", "cancelled", "failed"]
- status_details: Any
- output: List[ConversationItem]
- usage: Optional[Usage] = None
-
-
-_server_event_types = {
- "error": ErrorEvent,
- "session.created": SessionCreatedEvent,
- "session.updated": SessionUpdatedEvent,
- "conversation.created": ConversationCreated,
- "input_audio_buffer.committed": InputAudioBufferCommitted,
- "input_audio_buffer.cleared": InputAudioBufferCleared,
- "input_audio_buffer.speech_started": InputAudioBufferSpeechStarted,
- "input_audio_buffer.speech_stopped": InputAudioBufferSpeechStopped,
- "conversation.item.created": ConversationItemCreated,
- "conversation.item.input_audio_transcription.delta": ConversationItemInputAudioTranscriptionDelta,
- "conversation.item.input_audio_transcription.completed": ConversationItemInputAudioTranscriptionCompleted,
- "conversation.item.input_audio_transcription.failed": ConversationItemInputAudioTranscriptionFailed,
- "conversation.item.truncated": ConversationItemTruncated,
- "conversation.item.deleted": ConversationItemDeleted,
- "conversation.item.retrieved": ConversationItemRetrieved,
- "response.created": ResponseCreated,
- "response.done": ResponseDone,
- "response.output_item.added": ResponseOutputItemAdded,
- "response.output_item.done": ResponseOutputItemDone,
- "response.content_part.added": ResponseContentPartAdded,
- "response.content_part.done": ResponseContentPartDone,
- "response.text.delta": ResponseTextDelta,
- "response.text.done": ResponseTextDone,
- "response.audio_transcript.delta": ResponseAudioTranscriptDelta,
- "response.audio_transcript.done": ResponseAudioTranscriptDone,
- "response.audio.delta": ResponseAudioDelta,
- "response.audio.done": ResponseAudioDone,
- "response.function_call_arguments.delta": ResponseFunctionCallArgumentsDelta,
- "response.function_call_arguments.done": ResponseFunctionCallArgumentsDone,
- "rate_limits.updated": RateLimitsUpdated,
-}
-
-
-def parse_server_event(str):
- """Parse a server event from JSON string.
-
- Args:
- str: JSON string containing the server event.
-
- Returns:
- Parsed server event object of the appropriate type.
-
- Raises:
- Exception: If the event type is unimplemented or parsing fails.
- """
- try:
- event = json.loads(str)
- event_type = event["type"]
- if event_type not in _server_event_types:
- raise Exception(f"Unimplemented server event type: {event_type}")
- return _server_event_types[event_type].model_validate(event)
- except Exception as e:
- raise Exception(f"{e} \n\n{str}")
diff --git a/src/pipecat/services/openai_realtime_beta/frames.py b/src/pipecat/services/openai_realtime_beta/frames.py
deleted file mode 100644
index 02ef64000..000000000
--- a/src/pipecat/services/openai_realtime_beta/frames.py
+++ /dev/null
@@ -1,37 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
-
-"""Custom frame types for OpenAI Realtime API integration."""
-
-from dataclasses import dataclass
-from typing import TYPE_CHECKING
-
-from pipecat.frames.frames import DataFrame, FunctionCallResultFrame
-
-if TYPE_CHECKING:
- from pipecat.services.openai_realtime_beta.context import OpenAIRealtimeLLMContext
-
-
-@dataclass
-class RealtimeMessagesUpdateFrame(DataFrame):
- """Frame indicating that the realtime context messages have been updated.
-
- Parameters:
- context: The updated OpenAI realtime LLM context.
- """
-
- context: "OpenAIRealtimeLLMContext"
-
-
-@dataclass
-class RealtimeFunctionCallResultFrame(DataFrame):
- """Frame containing function call results for the realtime service.
-
- Parameters:
- result_frame: The function call result frame to send to the realtime API.
- """
-
- result_frame: FunctionCallResultFrame
diff --git a/src/pipecat/services/openai_realtime_beta/openai.py b/src/pipecat/services/openai_realtime_beta/openai.py
deleted file mode 100644
index 0d20039b1..000000000
--- a/src/pipecat/services/openai_realtime_beta/openai.py
+++ /dev/null
@@ -1,858 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
-
-"""OpenAI Realtime Beta LLM service implementation with WebSocket support."""
-
-import base64
-import json
-import time
-import warnings
-from dataclasses import dataclass
-from typing import Optional
-
-from loguru import logger
-
-from pipecat.adapters.services.open_ai_realtime_adapter import OpenAIRealtimeLLMAdapter
-from pipecat.frames.frames import (
- AggregationType,
- BotStoppedSpeakingFrame,
- CancelFrame,
- EndFrame,
- ErrorFrame,
- Frame,
- InputAudioRawFrame,
- InterimTranscriptionFrame,
- InterruptionFrame,
- LLMContextFrame,
- LLMFullResponseEndFrame,
- LLMFullResponseStartFrame,
- LLMMessagesAppendFrame,
- LLMSetToolsFrame,
- LLMTextFrame,
- LLMUpdateSettingsFrame,
- StartFrame,
- TranscriptionFrame,
- TTSAudioRawFrame,
- TTSStartedFrame,
- TTSStoppedFrame,
- TTSTextFrame,
- UserStartedSpeakingFrame,
- UserStoppedSpeakingFrame,
-)
-from pipecat.metrics.metrics import LLMTokenUsage
-from pipecat.processors.aggregators.llm_response import (
- LLMAssistantAggregatorParams,
- LLMUserAggregatorParams,
-)
-from pipecat.processors.aggregators.openai_llm_context import (
- OpenAILLMContext,
- OpenAILLMContextFrame,
-)
-from pipecat.processors.frame_processor import FrameDirection
-from pipecat.services.llm_service import FunctionCallFromLLM, LLMService
-from pipecat.services.openai.llm import OpenAIContextAggregatorPair
-from pipecat.services.settings import LLMSettings
-from pipecat.transcriptions.language import Language
-from pipecat.utils.time import time_now_iso8601
-from pipecat.utils.tracing.service_decorators import traced_openai_realtime, traced_stt
-
-from . import events
-from .context import (
- OpenAIRealtimeAssistantContextAggregator,
- OpenAIRealtimeLLMContext,
- OpenAIRealtimeUserContextAggregator,
-)
-from .frames import RealtimeFunctionCallResultFrame, RealtimeMessagesUpdateFrame
-
-try:
- from websockets.asyncio.client import connect as websocket_connect
-except ModuleNotFoundError as e:
- logger.error(f"Exception: {e}")
- logger.error("In order to use OpenAI, you need to `pip install pipecat-ai[openai]`.")
- raise Exception(f"Missing module: {e}")
-
-
-@dataclass
-class CurrentAudioResponse:
- """Tracks the current audio response from the assistant.
-
- Parameters:
- item_id: Unique identifier for the audio response item.
- content_index: Index of the audio content within the item.
- start_time_ms: Timestamp when the audio response started in milliseconds.
- total_size: Total size of audio data received in bytes. Defaults to 0.
- """
-
- item_id: str
- content_index: int
- start_time_ms: int
- total_size: int = 0
-
-
-@dataclass
-class OpenAIRealtimeBetaLLMSettings(LLMSettings):
- """Settings for OpenAIRealtimeBetaLLMService."""
-
- pass
-
-
-class OpenAIRealtimeBetaLLMService(LLMService):
- """OpenAI Realtime Beta LLM service providing real-time audio and text communication.
-
- .. deprecated:: 0.0.84
- `OpenAIRealtimeBetaLLMService` is deprecated, use `OpenAIRealtimeLLMService` instead.
- This class will be removed in version 1.0.0.
-
- Implements the OpenAI Realtime API Beta with WebSocket communication for low-latency
- bidirectional audio and text interactions. Supports function calling, conversation
- management, and real-time transcription.
- """
-
- Settings = OpenAIRealtimeBetaLLMSettings
- _settings: Settings
-
- # Overriding the default adapter to use the OpenAIRealtimeLLMAdapter one.
- adapter_class = OpenAIRealtimeLLMAdapter
-
- def __init__(
- self,
- *,
- api_key: str,
- model: Optional[str] = None,
- base_url: str = "wss://api.openai.com/v1/realtime",
- session_properties: Optional[events.SessionProperties] = None,
- settings: Optional[Settings] = None,
- start_audio_paused: bool = False,
- send_transcription_frames: bool = True,
- **kwargs,
- ):
- """Initialize the OpenAI Realtime Beta LLM service.
-
- Args:
- api_key: OpenAI API key for authentication.
- model: OpenAI model name.
-
- .. deprecated:: 0.0.105
- Use ``settings=OpenAIRealtimeBetaLLMService.Settings(model=...)`` instead.
-
- base_url: WebSocket base URL for the realtime API.
- Defaults to "wss://api.openai.com/v1/realtime".
- session_properties: Configuration properties for the realtime session.
- If None, uses default SessionProperties.
- settings: Runtime-updatable settings for this service.
- start_audio_paused: Whether to start with audio input paused. Defaults to False.
- send_transcription_frames: Whether to emit transcription frames. Defaults to True.
- **kwargs: Additional arguments passed to parent LLMService.
- """
- with warnings.catch_warnings():
- warnings.simplefilter("always")
- warnings.warn(
- "OpenAIRealtimeBetaLLMService is deprecated and will be removed in version 1.0.0. "
- "Use OpenAIRealtimeLLMService instead.",
- DeprecationWarning,
- stacklevel=2,
- )
-
- # 1. Initialize default_settings with hardcoded defaults
- default_settings = self.Settings(
- model="gpt-4o-realtime-preview-2025-06-03",
- system_instruction=None,
- temperature=None,
- max_tokens=None,
- top_p=None,
- top_k=None,
- frequency_penalty=None,
- presence_penalty=None,
- seed=None,
- filter_incomplete_user_turns=False,
- user_turn_completion_config=None,
- )
-
- # 2. Apply direct init arg overrides (deprecated)
- if model is not None:
- self._warn_init_param_moved_to_settings("model", "model")
- default_settings.model = model
- # 3. Apply settings delta (canonical API, always wins)
- if settings is not None:
- default_settings.apply_update(settings)
-
- full_url = f"{base_url}?model={default_settings.model}"
- super().__init__(
- base_url=full_url,
- settings=default_settings,
- **kwargs,
- )
-
- self.api_key = api_key
- self.base_url = full_url
- self._session_properties = session_properties or events.SessionProperties()
- self._audio_input_paused = start_audio_paused
- self._send_transcription_frames = send_transcription_frames
- self._websocket = None
- self._receive_task = None
- self._context = None
-
- self._disconnecting = False
- self._api_session_ready = False
- self._run_llm_when_api_session_ready = False
-
- self._current_assistant_response = None
- self._current_audio_response = None
-
- self._messages_added_manually = {}
- self._user_and_response_message_tuple = None
-
- self._register_event_handler("on_conversation_item_created")
- self._register_event_handler("on_conversation_item_updated")
- self._retrieve_conversation_item_futures = {}
-
- def can_generate_metrics(self) -> bool:
- """Check if the service can generate usage metrics.
-
- Returns:
- True if metrics generation is supported.
- """
- return True
-
- def set_audio_input_paused(self, paused: bool):
- """Set whether audio input is paused.
-
- Args:
- paused: True to pause audio input, False to resume.
- """
- self._audio_input_paused = paused
-
- def _is_modality_enabled(self, modality: str) -> bool:
- """Check if a specific modality is enabled, "text" or "audio"."""
- modalities = self._session_properties.modalities or ["audio", "text"]
- return modality in modalities
-
- def _get_enabled_modalities(self) -> list[str]:
- """Get the list of enabled modalities."""
- return self._session_properties.modalities or ["audio", "text"]
-
- async def retrieve_conversation_item(self, item_id: str):
- """Retrieve a conversation item by ID from the server.
-
- Args:
- item_id: The ID of the conversation item to retrieve.
-
- Returns:
- The retrieved conversation item.
- """
- future = self.get_event_loop().create_future()
- retrieval_in_flight = False
- if not self._retrieve_conversation_item_futures.get(item_id):
- self._retrieve_conversation_item_futures[item_id] = []
- else:
- retrieval_in_flight = True
- self._retrieve_conversation_item_futures[item_id].append(future)
- if not retrieval_in_flight:
- await self.send_client_event(
- # Set event_id to "rci_{item_id}" so that we can identify an
- # error later if the retrieval fails. We don't need a UUID
- # suffix to the event_id because we're ensuring only one
- # in-flight retrieval per item_id. (Note: "rci" = "retrieve
- # conversation item")
- events.ConversationItemRetrieveEvent(item_id=item_id, event_id=f"rci_{item_id}")
- )
- return await future
-
- #
- # standard AIService frame handling
- #
-
- async def start(self, frame: StartFrame):
- """Start the service and establish WebSocket connection.
-
- Args:
- frame: The start frame triggering service initialization.
- """
- await super().start(frame)
- await self._connect()
-
- async def stop(self, frame: EndFrame):
- """Stop the service and close WebSocket connection.
-
- Args:
- frame: The end frame triggering service shutdown.
- """
- await super().stop(frame)
- await self._disconnect()
-
- async def cancel(self, frame: CancelFrame):
- """Cancel the service and close WebSocket connection.
-
- Args:
- frame: The cancel frame triggering service cancellation.
- """
- await super().cancel(frame)
- await self._disconnect()
-
- #
- # speech and interruption handling
- #
-
- async def _handle_interruption(self):
- # None and False are different. Check for False. None means we're using OpenAI's
- # built-in turn detection defaults.
- if self._session_properties.turn_detection is False:
- await self.send_client_event(events.InputAudioBufferClearEvent())
- await self.send_client_event(events.ResponseCancelEvent())
- await self._truncate_current_audio_response()
- await self.stop_all_metrics()
- if self._current_assistant_response:
- await self.push_frame(LLMFullResponseEndFrame())
- # Only push TTSStoppedFrame if audio modality is enabled
- if self._is_modality_enabled("audio"):
- await self.push_frame(TTSStoppedFrame())
-
- async def _handle_user_started_speaking(self, frame):
- pass
-
- async def _handle_user_stopped_speaking(self, frame):
- # None and False are different. Check for False. None means we're using OpenAI's
- # built-in turn detection defaults.
- if self._session_properties.turn_detection is False:
- await self.send_client_event(events.InputAudioBufferCommitEvent())
- await self.send_client_event(events.ResponseCreateEvent())
-
- async def _handle_bot_stopped_speaking(self):
- self._current_audio_response = None
-
- def _calculate_audio_duration_ms(
- self, total_bytes: int, sample_rate: int = 24000, bytes_per_sample: int = 2
- ) -> int:
- """Calculate audio duration in milliseconds based on PCM audio parameters."""
- samples = total_bytes / bytes_per_sample
- duration_seconds = samples / sample_rate
- return int(duration_seconds * 1000)
-
- async def _truncate_current_audio_response(self):
- """Truncates the current audio response at the appropriate duration.
-
- Calculates the actual duration of the audio content and truncates at the shorter of
- either the wall clock time or the actual audio duration to prevent invalid truncation
- requests.
- """
- if not self._current_audio_response:
- return
-
- # if the bot is still speaking, truncate the last message
- try:
- current = self._current_audio_response
- self._current_audio_response = None
-
- # Calculate actual audio duration instead of using wall clock time
- audio_duration_ms = self._calculate_audio_duration_ms(current.total_size)
-
- # Use the shorter of wall clock time or actual audio duration
- elapsed_ms = int(time.time() * 1000 - current.start_time_ms)
- truncate_ms = min(elapsed_ms, audio_duration_ms)
-
- logger.trace(
- f"Truncating audio: duration={audio_duration_ms}ms, "
- f"elapsed={elapsed_ms}ms, truncate={truncate_ms}ms"
- )
-
- await self.send_client_event(
- events.ConversationItemTruncateEvent(
- item_id=current.item_id,
- content_index=current.content_index,
- audio_end_ms=truncate_ms,
- )
- )
- except Exception as e:
- # Log warning and don't re-raise - allow session to continue
- logger.warning(f"Audio truncation failed (non-fatal): {e}")
-
- #
- # frame processing
- #
- # StartFrame, StopFrame, CancelFrame implemented in base class
- #
-
- async def process_frame(self, frame: Frame, direction: FrameDirection):
- """Process incoming frames from the pipeline.
-
- Args:
- frame: The frame to process.
- direction: The direction of frame flow in the pipeline.
- """
- # Backward-compatible dict path: frame.settings contains SessionProperties
- # fields, not our Settings fields, so we construct SessionProperties
- # directly. The frame.delta path falls through to super, which calls
- # _update_settings → our override handles the rest.
- if isinstance(frame, LLMUpdateSettingsFrame) and frame.delta is None:
- self._session_properties = events.SessionProperties(**frame.settings)
- await self._send_session_update()
- await self.push_frame(frame, direction)
- return
-
- await super().process_frame(frame, direction)
-
- if isinstance(frame, TranscriptionFrame):
- pass
- elif isinstance(frame, OpenAILLMContextFrame):
- context: OpenAIRealtimeLLMContext = OpenAIRealtimeLLMContext.upgrade_to_realtime(
- frame.context
- )
- if not self._context:
- self._context = context
- elif frame.context is not self._context:
- # If the context has changed, reset the conversation
- self._context = context
- await self.reset_conversation()
- # Run the LLM at next opportunity
- await self._create_response()
- elif isinstance(frame, LLMContextFrame):
- raise NotImplementedError(
- "Universal LLMContext is not yet supported for OpenAI Realtime."
- )
- elif isinstance(frame, InputAudioRawFrame):
- if not self._audio_input_paused:
- await self._send_user_audio(frame)
- elif isinstance(frame, InterruptionFrame):
- await self._handle_interruption()
- elif isinstance(frame, UserStartedSpeakingFrame):
- await self._handle_user_started_speaking(frame)
- elif isinstance(frame, UserStoppedSpeakingFrame):
- await self._handle_user_stopped_speaking(frame)
- elif isinstance(frame, BotStoppedSpeakingFrame):
- await self._handle_bot_stopped_speaking()
- elif isinstance(frame, LLMMessagesAppendFrame):
- await self._handle_messages_append(frame)
- elif isinstance(frame, RealtimeMessagesUpdateFrame):
- self._context = frame.context
- elif isinstance(frame, LLMSetToolsFrame):
- await self._send_session_update()
- elif isinstance(frame, RealtimeFunctionCallResultFrame):
- await self._handle_function_call_result(frame.result_frame)
-
- await self.push_frame(frame, direction)
-
- async def _handle_messages_append(self, frame):
- logger.error("!!! NEED TO IMPLEMENT MESSAGES APPEND")
-
- async def _handle_function_call_result(self, frame):
- item = events.ConversationItem(
- type="function_call_output",
- call_id=frame.tool_call_id,
- output=json.dumps(frame.result, ensure_ascii=False),
- )
- await self.send_client_event(events.ConversationItemCreateEvent(item=item))
-
- #
- # websocket communication
- #
-
- async def send_client_event(self, event: events.ClientEvent):
- """Send a client event to the OpenAI Realtime API.
-
- Args:
- event: The client event to send.
- """
- await self._ws_send(event.model_dump(exclude_none=True))
-
- async def _connect(self):
- try:
- if self._websocket:
- # Here we assume that if we have a websocket, we are connected. We
- # handle disconnections in the send/recv code paths.
- return
- self._websocket = await websocket_connect(
- uri=self.base_url,
- additional_headers={
- "Authorization": f"Bearer {self.api_key}",
- "OpenAI-Beta": "realtime=v1",
- },
- )
- self._receive_task = self.create_task(self._receive_task_handler())
- except Exception as e:
- await self.push_error(error_msg=f"Error connecting: {e}", exception=e)
- self._websocket = None
-
- async def _disconnect(self):
- try:
- self._disconnecting = True
- self._api_session_ready = False
- await self.stop_all_metrics()
- if self._websocket:
- await self._websocket.close()
- self._websocket = None
- if self._receive_task:
- await self.cancel_task(self._receive_task, timeout=1.0)
- self._receive_task = None
- self._disconnecting = False
- except Exception as e:
- await self.push_error(error_msg=f"Error disconnecting: {e}", exception=e)
-
- async def _ws_send(self, realtime_message):
- try:
- if self._websocket:
- await self._websocket.send(json.dumps(realtime_message))
- except Exception as e:
- if self._disconnecting:
- return
- # In server-to-server contexts, a WebSocket error should be quite rare. Given how hard
- # it is to recover from a send-side error with proper state management, and that exponential
- # backoff for retries can have cost/stability implications for a service cluster, let's just
- # treat a send-side error as fatal.
- await self.push_error(error_msg=f"Error sending client event: {e}", exception=e)
-
- async def _update_settings(self, delta):
- """Apply a settings delta."""
- changed = await super()._update_settings(delta)
- self._warn_unhandled_updated_settings(changed.keys())
- return changed
-
- async def _send_session_update(self):
- settings = self._session_properties
- # tools given in the context override the tools in the session properties
- if self._context and self._context.tools:
- settings.tools = self._context.tools
- # instructions in the context come from an initial "system" message in the
- # messages list, and override instructions in the session properties
- if self._context and self._context._session_instructions:
- settings.instructions = self._context._session_instructions
- await self.send_client_event(events.SessionUpdateEvent(session=settings))
-
- #
- # inbound server event handling
- # https://platform.openai.com/docs/api-reference/realtime-server-events
- #
-
- async def _receive_task_handler(self):
- async for message in self._websocket:
- evt = events.parse_server_event(message)
- if evt.type == "session.created":
- await self._handle_evt_session_created(evt)
- elif evt.type == "session.updated":
- await self._handle_evt_session_updated(evt)
- elif evt.type == "response.audio.delta":
- await self._handle_evt_audio_delta(evt)
- elif evt.type == "response.audio.done":
- await self._handle_evt_audio_done(evt)
- elif evt.type == "conversation.item.created":
- await self._handle_evt_conversation_item_created(evt)
- elif evt.type == "conversation.item.input_audio_transcription.delta":
- await self._handle_evt_input_audio_transcription_delta(evt)
- elif evt.type == "conversation.item.input_audio_transcription.completed":
- await self.handle_evt_input_audio_transcription_completed(evt)
- elif evt.type == "conversation.item.retrieved":
- await self._handle_conversation_item_retrieved(evt)
- elif evt.type == "response.done":
- await self._handle_evt_response_done(evt)
- elif evt.type == "input_audio_buffer.speech_started":
- await self._handle_evt_speech_started(evt)
- elif evt.type == "input_audio_buffer.speech_stopped":
- await self._handle_evt_speech_stopped(evt)
- elif evt.type == "response.text.delta":
- await self._handle_evt_text_delta(evt)
- elif evt.type == "response.audio_transcript.delta":
- await self._handle_evt_audio_transcript_delta(evt)
- elif evt.type == "error":
- if not await self._maybe_handle_evt_retrieve_conversation_item_error(evt):
- if evt.error.code in (
- "response_cancel_not_active",
- "conversation_already_has_active_response",
- ):
- logger.debug(f"{self} {evt.error.message}")
- else:
- await self._handle_evt_error(evt)
- # errors are fatal, so exit the receive loop
- return
-
- @traced_openai_realtime(operation="llm_setup")
- async def _handle_evt_session_created(self, evt):
- # session.created is received right after connecting. Send a message
- # to configure the session properties.
- await self._send_session_update()
-
- async def _handle_evt_session_updated(self, evt):
- # If this is our first context frame, run the LLM
- self._api_session_ready = True
- # Now that we've configured the session, we can run the LLM if we need to.
- if self._run_llm_when_api_session_ready:
- self._run_llm_when_api_session_ready = False
- await self._create_response()
-
- async def _handle_evt_audio_delta(self, evt):
- # note: ttfb is faster by 1/2 RTT than ttfb as measured for other services, since we're getting
- # this event from the server
- await self.stop_ttfb_metrics()
-
- if self._current_audio_response and self._current_audio_response.item_id != evt.item_id:
- logger.warning(
- f"Received a new audio delta for an already completed audio response before receiving the BotStoppedSpeakingFrame."
- )
- logger.debug("Forcing previous audio response to None")
- self._current_audio_response = None
-
- if not self._current_audio_response:
- self._current_audio_response = CurrentAudioResponse(
- item_id=evt.item_id,
- content_index=evt.content_index,
- start_time_ms=int(time.time() * 1000),
- )
- await self.push_frame(TTSStartedFrame())
- audio = base64.b64decode(evt.delta)
- self._current_audio_response.total_size += len(audio)
- frame = TTSAudioRawFrame(
- audio=audio,
- sample_rate=24000,
- num_channels=1,
- )
- await self.push_frame(frame)
-
- async def _handle_evt_audio_done(self, evt):
- if self._current_audio_response:
- await self.push_frame(TTSStoppedFrame())
- # Don't clear the self._current_audio_response here. We need to wait until we
- # receive a BotStoppedSpeakingFrame from the output transport.
-
- async def _handle_evt_conversation_item_created(self, evt):
- await self._call_event_handler("on_conversation_item_created", evt.item.id, evt.item)
-
- # This will get sent from the server every time a new "message" is added
- # to the server's conversation state, whether we create it via the API
- # or the server creates it from LLM output.
- if self._messages_added_manually.get(evt.item.id):
- del self._messages_added_manually[evt.item.id]
- return
-
- if evt.item.role == "user":
- # We need to wait for completion of both user message and response message. Then we'll
- # add both to the context. User message is complete when we have a "transcript" field
- # that is not None. Response message is complete when we get a "response.done" event.
- self._user_and_response_message_tuple = (evt.item, {"done": False, "output": []})
- elif evt.item.role == "assistant":
- self._current_assistant_response = evt.item
- await self.push_frame(LLMFullResponseStartFrame())
-
- async def _handle_evt_input_audio_transcription_delta(self, evt):
- if self._send_transcription_frames:
- await self.push_frame(
- # no way to get a language code?
- InterimTranscriptionFrame(evt.delta, "", time_now_iso8601(), result=evt)
- )
-
- @traced_stt
- async def _handle_user_transcription(
- self, transcript: str, is_final: bool, language: Optional[Language] = None
- ):
- """Handle a transcription result with tracing."""
- pass
-
- async def handle_evt_input_audio_transcription_completed(self, evt):
- """Handle completion of input audio transcription.
-
- Args:
- evt: The transcription completed event.
- """
- await self._call_event_handler("on_conversation_item_updated", evt.item_id, None)
-
- if self._send_transcription_frames:
- await self.push_frame(
- # no way to get a language code?
- TranscriptionFrame(evt.transcript, "", time_now_iso8601(), result=evt)
- )
- await self._handle_user_transcription(evt.transcript, True, Language.EN)
- pair = self._user_and_response_message_tuple
- if pair:
- user, assistant = pair
- user.content[0].transcript = evt.transcript
- if assistant["done"]:
- self._user_and_response_message_tuple = None
- self._context.add_user_content_item_as_message(user)
- await self._handle_assistant_output(assistant["output"])
- else:
- # User message without preceding conversation.item.created. Bug?
- logger.warning(f"Transcript for unknown user message: {evt}")
-
- async def _handle_conversation_item_retrieved(self, evt: events.ConversationItemRetrieved):
- futures = self._retrieve_conversation_item_futures.pop(evt.item.id, None)
- if futures:
- for future in futures:
- future.set_result(evt.item)
-
- @traced_openai_realtime(operation="llm_response")
- async def _handle_evt_response_done(self, evt):
- # todo: figure out whether there's anything we need to do for "cancelled" events
- # usage metrics
- tokens = LLMTokenUsage(
- prompt_tokens=evt.response.usage.input_tokens,
- completion_tokens=evt.response.usage.output_tokens,
- total_tokens=evt.response.usage.total_tokens,
- )
- await self.start_llm_usage_metrics(tokens)
- await self.stop_processing_metrics()
- await self.push_frame(LLMFullResponseEndFrame())
- self._current_assistant_response = None
- # error handling
- if evt.response.status == "failed":
- await self.push_error(ErrorFrame(error=evt.response.status_details["error"]["message"]))
- return
- # response content
- for item in evt.response.output:
- await self._call_event_handler("on_conversation_item_updated", item.id, item)
- pair = self._user_and_response_message_tuple
- if pair:
- user, assistant = pair
- assistant["done"] = True
- assistant["output"] = evt.response.output
- if user.content[0].transcript is not None:
- self._user_and_response_message_tuple = None
- self._context.add_user_content_item_as_message(user)
- await self._handle_assistant_output(assistant["output"])
- else:
- # Response message without preceding user message. Add it to the context.
- await self._handle_assistant_output(evt.response.output)
-
- async def _handle_evt_text_delta(self, evt):
- if evt.delta:
- await self.push_frame(LLMTextFrame(evt.delta))
-
- async def _handle_evt_audio_transcript_delta(self, evt):
- if evt.delta:
- await self.push_frame(LLMTextFrame(evt.delta))
- await self.push_frame(TTSTextFrame(evt.delta, aggregated_by=AggregationType.SENTENCE))
-
- async def _handle_evt_speech_started(self, evt):
- await self._truncate_current_audio_response()
- await self.broadcast_frame(UserStartedSpeakingFrame)
- await self.broadcast_interruption()
-
- async def _handle_evt_speech_stopped(self, evt):
- await self.start_ttfb_metrics()
- await self.start_processing_metrics()
- await self.broadcast_frame(UserStoppedSpeakingFrame)
-
- async def _maybe_handle_evt_retrieve_conversation_item_error(self, evt: events.ErrorEvent):
- """Maybe handle an error event related to retrieving a conversation item.
-
- If the given error event is an error retrieving a conversation item:
-
- - set an exception on the future that retrieve_conversation_item() is waiting on
- - return true
- Otherwise:
- - return false
- """
- if evt.error.code == "item_retrieve_invalid_item_id":
- item_id = evt.error.event_id.split("_", 1)[1] # event_id is of the form "rci_{item_id}"
- futures = self._retrieve_conversation_item_futures.pop(item_id, None)
- if futures:
- for future in futures:
- future.set_exception(Exception(evt.error.message))
- return True
- return False
-
- async def _handle_evt_error(self, evt):
- # Errors are fatal to this connection. Send an ErrorFrame.
- await self.push_error(error_msg=f"Error: {evt}")
-
- async def _handle_assistant_output(self, output):
- # We haven't seen intermixed audio and function_call items in the same response. But let's
- # try to write logic that handles that, if it does happen.
- # Also, the assistant output is pushed as LLMTextFrame and TTSTextFrame to be handled by
- # the assistant context aggregator.
- function_calls = [item for item in output if item.type == "function_call"]
- await self._handle_function_call_items(function_calls)
-
- async def _handle_function_call_items(self, items):
- function_calls = []
- for item in items:
- args = json.loads(item.arguments)
- function_calls.append(
- FunctionCallFromLLM(
- context=self._context,
- tool_call_id=item.call_id,
- function_name=item.name,
- arguments=args,
- )
- )
- await self.run_function_calls(function_calls)
-
- #
- # state and client events for the current conversation
- # https://platform.openai.com/docs/api-reference/realtime-client-events
- #
-
- async def reset_conversation(self):
- """Reset the conversation by disconnecting and reconnecting.
-
- This is the safest way to start a new conversation. Note that this will
- fail if called from the receive task.
- """
- logger.debug("Resetting conversation")
- await self._disconnect()
- if self._context:
- self._context.llm_needs_settings_update = True
- self._context.llm_needs_initial_messages = True
- await self._connect()
-
- @traced_openai_realtime(operation="llm_request")
- async def _create_response(self):
- if not self._api_session_ready:
- self._run_llm_when_api_session_ready = True
- return
-
- if self._context.llm_needs_initial_messages:
- messages = self._context.get_messages_for_initializing_history()
- for item in messages:
- evt = events.ConversationItemCreateEvent(item=item)
- self._messages_added_manually[evt.item.id] = True
- await self.send_client_event(evt)
- self._context.llm_needs_initial_messages = False
-
- if self._context.llm_needs_settings_update:
- await self._send_session_update()
- self._context.llm_needs_settings_update = False
-
- logger.debug(f"Creating response: {self._context.get_messages_for_logging()}")
-
- await self.push_frame(LLMFullResponseStartFrame())
- await self.start_processing_metrics()
- await self.start_ttfb_metrics()
- await self.send_client_event(
- events.ResponseCreateEvent(
- response=events.ResponseProperties(modalities=self._get_enabled_modalities())
- )
- )
-
- async def _send_user_audio(self, frame):
- payload = base64.b64encode(frame.audio).decode("utf-8")
- await self.send_client_event(events.InputAudioBufferAppendEvent(audio=payload))
-
- def create_context_aggregator(
- self,
- context: OpenAILLMContext,
- *,
- user_params: LLMUserAggregatorParams = LLMUserAggregatorParams(),
- assistant_params: LLMAssistantAggregatorParams = LLMAssistantAggregatorParams(),
- ) -> OpenAIContextAggregatorPair:
- """Create an instance of OpenAIContextAggregatorPair from an OpenAILLMContext.
-
- Constructor keyword arguments for both the user and assistant aggregators can be provided.
-
- Args:
- context: The LLM context.
- user_params: User aggregator parameters.
- assistant_params: Assistant aggregator parameters.
-
- Returns:
- OpenAIContextAggregatorPair: A pair of context aggregators, one for
- the user and one for the assistant, encapsulated in an
- OpenAIContextAggregatorPair.
- """
- context.set_llm_adapter(self.get_llm_adapter())
-
- OpenAIRealtimeLLMContext.upgrade_to_realtime(context)
- user = OpenAIRealtimeUserContextAggregator(context, params=user_params)
-
- assistant_params.expect_stripped_words = False
- assistant = OpenAIRealtimeAssistantContextAggregator(context, params=assistant_params)
- return OpenAIContextAggregatorPair(_user=user, _assistant=assistant)
diff --git a/src/pipecat/services/riva/__init__.py b/src/pipecat/services/riva/__init__.py
deleted file mode 100644
index eb438ef8a..000000000
--- a/src/pipecat/services/riva/__init__.py
+++ /dev/null
@@ -1,14 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
-
-import sys
-
-from pipecat.services import DeprecatedModuleProxy
-
-from .stt import *
-from .tts import *
-
-sys.modules[__name__] = DeprecatedModuleProxy(globals(), "riva", "riva.[stt,tts]")
diff --git a/src/pipecat/services/riva/stt.py b/src/pipecat/services/riva/stt.py
deleted file mode 100644
index 45faf08a0..000000000
--- a/src/pipecat/services/riva/stt.py
+++ /dev/null
@@ -1,35 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
-
-"""NVIDIA Riva Speech-to-Text service implementations for real-time and batch transcription.
-
-.. deprecated:: 0.0.96
- This module is deprecated. Please NvidiaSTTService from
- pipecat.services.nvidia.stt instead.
-"""
-
-import warnings
-
-from pipecat.services.nvidia.stt import (
- NvidiaSegmentedSTTService,
- NvidiaSTTService,
- language_to_nvidia_riva_language,
-)
-
-with warnings.catch_warnings():
- warnings.simplefilter("always")
- warnings.warn(
- "RivaSTTService and ParakeetSTTService "
- "from pipecat.services.riva.stt is deprecated. "
- "Please use NvidiaSTTService from pipecat.services.nvidia.stt instead.",
- DeprecationWarning,
- stacklevel=2,
- )
-
-RivaSTTService = NvidiaSTTService
-language_to_riva_language = language_to_nvidia_riva_language
-RivaSegmentedSTTService = NvidiaSegmentedSTTService
-ParakeetSTTService = NvidiaSTTService
diff --git a/src/pipecat/services/riva/tts.py b/src/pipecat/services/riva/tts.py
deleted file mode 100644
index 7b0af3d39..000000000
--- a/src/pipecat/services/riva/tts.py
+++ /dev/null
@@ -1,33 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
-
-"""NVIDIA Riva text-to-speech service implementation.
-
-This module provides integration with NVIDIA Riva's TTS services through
-gRPC API for high-quality speech synthesis.
-
-.. deprecated:: 0.0.96
- This module is deprecated. Please NvidiaTTSService from
- pipecat.services.nvidia.tts instead.
-"""
-
-import warnings
-
-from pipecat.services.nvidia.tts import NVIDIA_TTS_TIMEOUT_SECS, NvidiaTTSService
-
-with warnings.catch_warnings():
- warnings.simplefilter("always")
- warnings.warn(
- "FastPitchTTSService and RivaTTSService "
- "from pipecat.services.nim.llm are deprecated. "
- "Please use NvidiaLLMService from pipecat.services.nvidia.tts instead.",
- DeprecationWarning,
- stacklevel=2,
- )
-
-RivaTTSService = NvidiaTTSService
-FastPitchTTSService = NvidiaTTSService
-RIVA_TTS_TIMEOUT_SECS = NVIDIA_TTS_TIMEOUT_SECS
diff --git a/src/pipecat/utils/tracing/service_attributes.py b/src/pipecat/utils/tracing/service_attributes.py
index e5cf4a83f..5be781406 100644
--- a/src/pipecat/utils/tracing/service_attributes.py
+++ b/src/pipecat/utils/tracing/service_attributes.py
@@ -47,7 +47,6 @@ def _get_provider_name_from_service_name(service_name: str) -> str:
"AzureLLMService": "az.ai.openai",
# Google
"GoogleLLMService": "gcp.gemini",
- "GoogleLLMOpenAIBetaService": "gcp.gemini",
"GoogleVertexLLMService": "gcp.vertex_ai",
# Others
"GrokLLMService": "xai",
diff --git a/tests/test_google_llm_openai.py b/tests/test_google_llm_openai.py
deleted file mode 100644
index 5e6cee6f8..000000000
--- a/tests/test_google_llm_openai.py
+++ /dev/null
@@ -1,81 +0,0 @@
-#
-# Copyright (c) 2024-2026, Daily
-#
-# SPDX-License-Identifier: BSD 2-Clause License
-#
-
-"""Unit tests for Google LLM OpenAI Beta service."""
-
-import asyncio
-import warnings
-from unittest.mock import AsyncMock, patch
-
-import pytest
-
-from pipecat.processors.aggregators.openai_llm_context import OpenAILLMContext
-
-try:
- from pipecat.services.google.openai.llm import GoogleLLMOpenAIBetaService
-
- google_available = True
-except Exception:
- google_available = False
-
-
-@pytest.mark.asyncio
-@pytest.mark.skipif(not google_available, reason="Google dependencies not installed")
-async def test_google_llm_openai_stream_closed_on_cancellation():
- """Test that the stream is closed when CancelledError occurs during iteration.
-
- This prevents socket leaks when the pipeline is interrupted (e.g., user interruption).
- See issue #3639.
- """
- with patch.object(GoogleLLMOpenAIBetaService, "create_client"):
- with warnings.catch_warnings():
- warnings.simplefilter("ignore", DeprecationWarning)
- service = GoogleLLMOpenAIBetaService(api_key="test-key", model="test-model")
- service._client = AsyncMock()
-
- stream_closed = False
-
- class MockAsyncStream:
- """Mock AsyncStream that tracks close() calls and raises CancelledError."""
-
- def __init__(self):
- self.iteration_count = 0
-
- async def __aenter__(self):
- return self
-
- async def __aexit__(self, exc_type, exc_val, exc_tb):
- nonlocal stream_closed
- stream_closed = True
- return False
-
- def __aiter__(self):
- return self
-
- async def __anext__(self):
- self.iteration_count += 1
- if self.iteration_count > 1:
- raise asyncio.CancelledError()
- mock_chunk = AsyncMock()
- mock_chunk.usage = None
- mock_chunk.choices = []
- return mock_chunk
-
- mock_stream = MockAsyncStream()
-
- service._stream_chat_completions_specific_context = AsyncMock(return_value=mock_stream)
- service.start_ttfb_metrics = AsyncMock()
- service.stop_ttfb_metrics = AsyncMock()
- service.start_llm_usage_metrics = AsyncMock()
-
- context = OpenAILLMContext(
- messages=[{"role": "user", "content": "Hello"}],
- )
-
- with pytest.raises(asyncio.CancelledError):
- await service._process_context(context)
-
- assert stream_closed, "Stream should be closed even when CancelledError occurs"
diff --git a/tests/test_settings.py b/tests/test_settings.py
index 3419f940e..1607fdc3a 100644
--- a/tests/test_settings.py
+++ b/tests/test_settings.py
@@ -8,8 +8,8 @@
from unittest.mock import patch
+from pipecat.services.deepgram.sagemaker.stt import DeepgramSageMakerSTTSettings
from pipecat.services.deepgram.stt import DeepgramSTTService, DeepgramSTTSettings
-from pipecat.services.deepgram.stt_sagemaker import DeepgramSageMakerSTTSettings
from pipecat.services.openai.realtime import events
from pipecat.services.openai.realtime.llm import OpenAIRealtimeLLMSettings
from pipecat.services.settings import (
From 04e84440967a4f00789a7bfa833d6cc9534d1699 Mon Sep 17 00:00:00 2001
From: Mark Backman
Date: Mon, 30 Mar 2026 20:49:39 -0400
Subject: [PATCH 15/19] Add changelog for #4208
---
changelog/4208.removed.10.md | 1 +
changelog/4208.removed.11.md | 1 +
changelog/4208.removed.2.md | 1 +
changelog/4208.removed.3.md | 1 +
changelog/4208.removed.4.md | 1 +
changelog/4208.removed.5.md | 1 +
changelog/4208.removed.6.md | 1 +
changelog/4208.removed.7.md | 1 +
changelog/4208.removed.8.md | 1 +
changelog/4208.removed.9.md | 1 +
changelog/4208.removed.md | 1 +
11 files changed, 11 insertions(+)
create mode 100644 changelog/4208.removed.10.md
create mode 100644 changelog/4208.removed.11.md
create mode 100644 changelog/4208.removed.2.md
create mode 100644 changelog/4208.removed.3.md
create mode 100644 changelog/4208.removed.4.md
create mode 100644 changelog/4208.removed.5.md
create mode 100644 changelog/4208.removed.6.md
create mode 100644 changelog/4208.removed.7.md
create mode 100644 changelog/4208.removed.8.md
create mode 100644 changelog/4208.removed.9.md
create mode 100644 changelog/4208.removed.md
diff --git a/changelog/4208.removed.10.md b/changelog/4208.removed.10.md
new file mode 100644
index 000000000..62aa13468
--- /dev/null
+++ b/changelog/4208.removed.10.md
@@ -0,0 +1 @@
+- ⚠️ Removed deprecated `pipecat.services.riva` package. Use `pipecat.services.nvidia.stt` and `pipecat.services.nvidia.tts` instead (`RivaSTTService` → `NvidiaSTTService`, `RivaTTSService` → `NvidiaTTSService`).
diff --git a/changelog/4208.removed.11.md b/changelog/4208.removed.11.md
new file mode 100644
index 000000000..264eac200
--- /dev/null
+++ b/changelog/4208.removed.11.md
@@ -0,0 +1 @@
+- ⚠️ Removed deprecated `pipecat.services.nim` package. Use `pipecat.services.nvidia.llm` instead (`NimLLMService` → `NvidiaLLMService`).
diff --git a/changelog/4208.removed.2.md b/changelog/4208.removed.2.md
new file mode 100644
index 000000000..495e1091d
--- /dev/null
+++ b/changelog/4208.removed.2.md
@@ -0,0 +1 @@
+- ⚠️ Removed deprecated `pipecat.services.gemini_multimodal_live` package. Use `pipecat.services.google.gemini_live` instead. Note that class names no longer include "Multimodal" (e.g. `GeminiMultimodalLiveLLMService` → `GeminiLiveLLMService`).
diff --git a/changelog/4208.removed.3.md b/changelog/4208.removed.3.md
new file mode 100644
index 000000000..694cd08da
--- /dev/null
+++ b/changelog/4208.removed.3.md
@@ -0,0 +1 @@
+- ⚠️ Removed deprecated `pipecat.services.aws_nova_sonic` package. Use `pipecat.services.aws.nova_sonic` instead.
diff --git a/changelog/4208.removed.4.md b/changelog/4208.removed.4.md
new file mode 100644
index 000000000..bae411d95
--- /dev/null
+++ b/changelog/4208.removed.4.md
@@ -0,0 +1 @@
+- ⚠️ Removed deprecated `pipecat.services.openai_realtime` package. Use `pipecat.services.openai.realtime` instead.
diff --git a/changelog/4208.removed.5.md b/changelog/4208.removed.5.md
new file mode 100644
index 000000000..2f7ab0399
--- /dev/null
+++ b/changelog/4208.removed.5.md
@@ -0,0 +1 @@
+- ⚠️ Removed deprecated `OpenAIRealtimeBetaLLMService` and `AzureRealtimeBetaLLMService`. Use `OpenAIRealtimeLLMService` and `AzureRealtimeLLMService` from `pipecat.services.openai.realtime` and `pipecat.services.azure.realtime` instead.
diff --git a/changelog/4208.removed.6.md b/changelog/4208.removed.6.md
new file mode 100644
index 000000000..92ff7ce0c
--- /dev/null
+++ b/changelog/4208.removed.6.md
@@ -0,0 +1 @@
+- ⚠️ Removed deprecated `pipecat.services.deepgram.stt_sagemaker` and `pipecat.services.deepgram.tts_sagemaker` modules. Use `pipecat.services.deepgram.sagemaker.stt` and `pipecat.services.deepgram.sagemaker.tts` instead.
diff --git a/changelog/4208.removed.7.md b/changelog/4208.removed.7.md
new file mode 100644
index 000000000..9906d981c
--- /dev/null
+++ b/changelog/4208.removed.7.md
@@ -0,0 +1 @@
+- ⚠️ Removed deprecated `GoogleLLMOpenAIBetaService` from `pipecat.services.google.openai`. Use `GoogleLLMService` from `pipecat.services.google.llm` instead.
diff --git a/changelog/4208.removed.8.md b/changelog/4208.removed.8.md
new file mode 100644
index 000000000..92255f110
--- /dev/null
+++ b/changelog/4208.removed.8.md
@@ -0,0 +1 @@
+- ⚠️ Removed deprecated `pipecat.services.google.llm_vertex` module. Use `pipecat.services.google.vertex.llm` instead.
diff --git a/changelog/4208.removed.9.md b/changelog/4208.removed.9.md
new file mode 100644
index 000000000..c76fa8e90
--- /dev/null
+++ b/changelog/4208.removed.9.md
@@ -0,0 +1 @@
+- ⚠️ Removed deprecated `pipecat.services.google.gemini_live.llm_vertex` module. Use `pipecat.services.google.gemini_live.vertex.llm` instead.
diff --git a/changelog/4208.removed.md b/changelog/4208.removed.md
new file mode 100644
index 000000000..8f8e09988
--- /dev/null
+++ b/changelog/4208.removed.md
@@ -0,0 +1 @@
+- ⚠️ Removed deprecated `pipecat.services.ai_services` module. Import from `pipecat.services.ai_service`, `pipecat.services.llm_service`, `pipecat.services.stt_service`, `pipecat.services.tts_service`, etc. instead.
From 692c3c74d16530f6134294d2f464388c729778b1 Mon Sep 17 00:00:00 2001
From: mattie ruth backman
Date: Tue, 31 Mar 2026 09:23:54 -0400
Subject: [PATCH 16/19] We should now expect clients to be version 1.0.0 with
valid versioning info
---
.../processors/frameworks/rtvi/processor.py | 26 ++++++++++---------
1 file changed, 14 insertions(+), 12 deletions(-)
diff --git a/src/pipecat/processors/frameworks/rtvi/processor.py b/src/pipecat/processors/frameworks/rtvi/processor.py
index 69a863594..ee37573fd 100644
--- a/src/pipecat/processors/frameworks/rtvi/processor.py
+++ b/src/pipecat/processors/frameworks/rtvi/processor.py
@@ -57,7 +57,6 @@ class RTVIProcessor(FrameProcessor):
"""Initialize the RTVI processor.
Args:
- config: Initial RTVI configuration.
transport: Transport layer for communication.
**kwargs: Additional arguments passed to parent class.
"""
@@ -66,9 +65,8 @@ class RTVIProcessor(FrameProcessor):
self._bot_ready = False
self._client_ready = False
self._client_ready_id = ""
- # Default to 0.3.0 which is the last version before actually having a
- # "client-version".
- self._client_version = [0, 3, 0]
+ # Default to 0.0.0 to indicate unknown version.
+ self._client_version = [0, 0, 0]
self._llm_skip_tts: bool = False # Keep in sync with llm_service.py's configuration.
# A task to process incoming transport messages.
@@ -273,9 +271,6 @@ class RTVIProcessor(FrameProcessor):
try:
data = RTVI.ClientReadyData.model_validate(message.data)
except ValidationError:
- # Not all clients have been updated to RTVI 1.0.0.
- # For now, that's okay, we just log their info as unknown.
- data = None
pass
await self._handle_client_ready(message.id, data)
case "disconnect-bot":
@@ -306,12 +301,23 @@ class RTVIProcessor(FrameProcessor):
"""Handle the client-ready message from the client."""
version = data.version if data else None
logger.debug(f"Received client-ready: version {version}")
+ version_error = None
if version:
try:
self._client_version = [int(v) for v in version.split(".")]
+ protocol_major = int(RTVI.PROTOCOL_VERSION.split(".")[0])
+ if self._client_version[0] != protocol_major:
+ version_error = f"RTVI version {version} is not compatible with server protocol {RTVI.PROTOCOL_VERSION}."
except ValueError:
- logger.warning(f"Invalid client version format: {version}")
+ version_error = f"Invalid client version format ({version})."
+ else:
+ version_error = "Client version unknown."
about = data.about if data else {"library": "unknown"}
+ if version_error:
+ version_error += " Compatibility issues may occur."
+ logger.warning(version_error)
+ await self._send_error_response(request_id, version_error)
+
logger.debug(f"Client Details: {about}")
if self._input_transport:
await self._input_transport.start_audio_in_streaming()
@@ -413,7 +419,3 @@ class RTVIProcessor(FrameProcessor):
"""Send an error response message."""
message = RTVI.ErrorResponse(id=id, data=RTVI.ErrorResponseData(error=error))
await self.push_transport_message(message)
-
- def _action_id(self, service: str, action: str) -> str:
- """Generate an action ID from service and action names."""
- return f"{service}:{action}"
From 565b9b961dbfe7a3ea6b790b8e6de7f028c6a10b Mon Sep 17 00:00:00 2001
From: mattie ruth backman
Date: Tue, 31 Mar 2026 11:23:21 -0400
Subject: [PATCH 17/19] add tests for rtvi versioning
---
tests/test_rtvi_processor.py | 113 +++++++++++++++++++++++++++++++++++
1 file changed, 113 insertions(+)
create mode 100644 tests/test_rtvi_processor.py
diff --git a/tests/test_rtvi_processor.py b/tests/test_rtvi_processor.py
new file mode 100644
index 000000000..003619f40
--- /dev/null
+++ b/tests/test_rtvi_processor.py
@@ -0,0 +1,113 @@
+#
+# Copyright (c) 2024-2026, Daily
+#
+# SPDX-License-Identifier: BSD 2-Clause License
+#
+
+import unittest
+from unittest.mock import AsyncMock, patch
+
+import pipecat.processors.frameworks.rtvi.models as RTVI
+from pipecat.processors.frameworks.rtvi.processor import RTVIProcessor
+
+
+class TestRTVIClientReadyVersionHandling(unittest.IsolatedAsyncioTestCase):
+ def setUp(self):
+ self.processor = RTVIProcessor()
+
+ async def asyncTearDown(self):
+ await self.processor.cleanup()
+
+ async def _call_handle_client_ready(self, data):
+ """Helper to call _handle_client_ready with a mocked _send_error_response."""
+ self.processor._send_error_response = AsyncMock()
+ self.processor._input_transport = None
+ self.processor.set_client_ready = AsyncMock()
+ await self.processor._handle_client_ready("req-1", data)
+
+ async def test_valid_version_1_0_0_sends_no_error(self):
+ data = RTVI.ClientReadyData(
+ version="1.0.0",
+ about=RTVI.AboutClientData(library="test-client"),
+ )
+ await self._call_handle_client_ready(data)
+ self.processor._send_error_response.assert_not_called()
+ self.assertEqual(self.processor._client_version, [1, 0, 0])
+
+ async def test_valid_version_1_2_0_sends_no_error(self):
+ data = RTVI.ClientReadyData(
+ version="1.2.0",
+ about=RTVI.AboutClientData(library="test-client"),
+ )
+ await self._call_handle_client_ready(data)
+ self.processor._send_error_response.assert_not_called()
+ self.assertEqual(self.processor._client_version, [1, 2, 0])
+
+ async def test_version_below_1_0_0_sends_error(self):
+ data = RTVI.ClientReadyData(
+ version="0.3.0",
+ about=RTVI.AboutClientData(library="test-client"),
+ )
+ await self._call_handle_client_ready(data)
+ self.processor._send_error_response.assert_called_once()
+ error_msg = self.processor._send_error_response.call_args[0][1]
+ self.assertIn("0.3.0", error_msg)
+ self.assertIn("not compatible", error_msg)
+
+ async def test_version_above_protocol_major_sends_error(self):
+ data = RTVI.ClientReadyData(
+ version="2.3.1",
+ about=RTVI.AboutClientData(library="test-client"),
+ )
+ await self._call_handle_client_ready(data)
+ self.processor._send_error_response.assert_called_once()
+ error_msg = self.processor._send_error_response.call_args[0][1]
+ self.assertIn("2.3.1", error_msg)
+ self.assertIn("not compatible", error_msg)
+
+ async def test_no_version_sends_error(self):
+ """Client sends no data (data=None)."""
+ await self._call_handle_client_ready(None)
+ self.processor._send_error_response.assert_called_once()
+ error_msg = self.processor._send_error_response.call_args[0][1]
+ self.assertIn("unknown", error_msg)
+
+ async def test_invalid_version_format_sends_error(self):
+ data = RTVI.ClientReadyData(
+ version="not-a-version",
+ about=RTVI.AboutClientData(library="test-client"),
+ )
+ await self._call_handle_client_ready(data)
+ self.processor._send_error_response.assert_called_once()
+ error_msg = self.processor._send_error_response.call_args[0][1]
+ self.assertIn("Invalid client version format", error_msg)
+ self.assertIn("not-a-version", error_msg)
+
+ async def test_error_message_includes_compatibility_warning(self):
+ """All version errors should append the compatibility warning."""
+ for version in ["0.9.9", "2.0.0"]:
+ with self.subTest(version=version):
+ data = RTVI.ClientReadyData(
+ version=version,
+ about=RTVI.AboutClientData(library="test-client"),
+ )
+ await self._call_handle_client_ready(data)
+ error_msg = self.processor._send_error_response.call_args[0][1]
+ self.assertIn("Compatibility issues may occur", error_msg)
+
+ async def test_client_ready_is_set_even_on_version_error(self):
+ """Client-ready state should be set regardless of version errors."""
+ data = RTVI.ClientReadyData(
+ version="0.3.0",
+ about=RTVI.AboutClientData(library="test-client"),
+ )
+ await self._call_handle_client_ready(data)
+ self.processor.set_client_ready.assert_called_once()
+
+ async def test_client_ready_is_set_when_no_data(self):
+ await self._call_handle_client_ready(None)
+ self.processor.set_client_ready.assert_called_once()
+
+
+if __name__ == "__main__":
+ unittest.main()
From 3e255f3d211f61382a0860da7b99d7a40ca750be Mon Sep 17 00:00:00 2001
From: mattie ruth backman
Date: Tue, 31 Mar 2026 12:24:11 -0400
Subject: [PATCH 18/19] improve version format check
---
.../processors/frameworks/rtvi/processor.py | 5 ++++-
tests/test_rtvi_processor.py | 21 +++++++++++--------
2 files changed, 16 insertions(+), 10 deletions(-)
diff --git a/src/pipecat/processors/frameworks/rtvi/processor.py b/src/pipecat/processors/frameworks/rtvi/processor.py
index ee37573fd..8c8de903e 100644
--- a/src/pipecat/processors/frameworks/rtvi/processor.py
+++ b/src/pipecat/processors/frameworks/rtvi/processor.py
@@ -304,7 +304,10 @@ class RTVIProcessor(FrameProcessor):
version_error = None
if version:
try:
- self._client_version = [int(v) for v in version.split(".")]
+ parts = [int(v) for v in version.split(".")]
+ if len(parts) != 3:
+ raise ValueError
+ self._client_version = parts
protocol_major = int(RTVI.PROTOCOL_VERSION.split(".")[0])
if self._client_version[0] != protocol_major:
version_error = f"RTVI version {version} is not compatible with server protocol {RTVI.PROTOCOL_VERSION}."
diff --git a/tests/test_rtvi_processor.py b/tests/test_rtvi_processor.py
index 003619f40..36ff60b56 100644
--- a/tests/test_rtvi_processor.py
+++ b/tests/test_rtvi_processor.py
@@ -73,15 +73,18 @@ class TestRTVIClientReadyVersionHandling(unittest.IsolatedAsyncioTestCase):
self.assertIn("unknown", error_msg)
async def test_invalid_version_format_sends_error(self):
- data = RTVI.ClientReadyData(
- version="not-a-version",
- about=RTVI.AboutClientData(library="test-client"),
- )
- await self._call_handle_client_ready(data)
- self.processor._send_error_response.assert_called_once()
- error_msg = self.processor._send_error_response.call_args[0][1]
- self.assertIn("Invalid client version format", error_msg)
- self.assertIn("not-a-version", error_msg)
+ bad_versions = ["not-a-version", "123", "1.2.3.0", "junk", "1.2"]
+ for version in bad_versions:
+ with self.subTest(version=version):
+ data = RTVI.ClientReadyData(
+ version=version,
+ about=RTVI.AboutClientData(library="test-client"),
+ )
+ await self._call_handle_client_ready(data)
+ self.processor._send_error_response.assert_called_once()
+ error_msg = self.processor._send_error_response.call_args[0][1]
+ self.assertIn("Invalid client version format", error_msg)
+ self.assertIn(version, error_msg)
async def test_error_message_includes_compatibility_warning(self):
"""All version errors should append the compatibility warning."""
From 0f470767032780a16680341b4e94dd53f55563d2 Mon Sep 17 00:00:00 2001
From: mattie ruth backman
Date: Tue, 31 Mar 2026 15:11:22 -0400
Subject: [PATCH 19/19] More RTVI version parsing improvements
---
.../processors/frameworks/rtvi/processor.py | 17 +++++++++++++----
tests/test_rtvi_processor.py | 2 +-
2 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/src/pipecat/processors/frameworks/rtvi/processor.py b/src/pipecat/processors/frameworks/rtvi/processor.py
index 8c8de903e..0a05560c0 100644
--- a/src/pipecat/processors/frameworks/rtvi/processor.py
+++ b/src/pipecat/processors/frameworks/rtvi/processor.py
@@ -268,10 +268,19 @@ class RTVIProcessor(FrameProcessor):
match message.type:
case "client-ready":
data = None
- try:
- data = RTVI.ClientReadyData.model_validate(message.data)
- except ValidationError:
- pass
+ raw = message.data or {}
+ version = raw.get("version")
+ if isinstance(version, str):
+ about = RTVI.AboutClientData(library="unknown")
+ about_raw = raw.get("about")
+ if about_raw is not None:
+ try:
+ about = RTVI.AboutClientData.model_validate(about_raw)
+ except ValidationError:
+ logger.warning(
+ "Invalid 'about' data in client-ready message, ignoring."
+ )
+ data = RTVI.ClientReadyData(version=version, about=about)
await self._handle_client_ready(message.id, data)
case "disconnect-bot":
await self.push_frame(EndTaskFrame(), FrameDirection.UPSTREAM)
diff --git a/tests/test_rtvi_processor.py b/tests/test_rtvi_processor.py
index 36ff60b56..259b970dd 100644
--- a/tests/test_rtvi_processor.py
+++ b/tests/test_rtvi_processor.py
@@ -5,7 +5,7 @@
#
import unittest
-from unittest.mock import AsyncMock, patch
+from unittest.mock import AsyncMock
import pipecat.processors.frameworks.rtvi.models as RTVI
from pipecat.processors.frameworks.rtvi.processor import RTVIProcessor