Skip to content

Pipecat and Livekit integrations examples#20

Open
ianbbqzy wants to merge 27 commits into
mainfrom
ian/livekit-integrations
Open

Pipecat and Livekit integrations examples#20
ianbbqzy wants to merge 27 commits into
mainfrom
ian/livekit-integrations

Conversation

@ianbbqzy

Copy link
Copy Markdown
Contributor

No description provided.

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.


Ian Lee seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

@ianbbqzy ianbbqzy force-pushed the ian/livekit-integrations branch 2 times, most recently from ab812bc to 86633ca Compare February 13, 2026 22:59
@ianbbqzy ianbbqzy force-pushed the ian/livekit-integrations branch from 86633ca to 194b745 Compare March 2, 2026 23:26
Copilot AI review requested due to automatic review settings March 2, 2026 23:26

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Pipecat and LiveKit integration examples (quickstarts + benchmarks) to help developers test Inworld TTS and compare TTFB across multiple providers.

Changes:

  • Added Pipecat quickstart bot + UV project config and environment template.
  • Added Pipecat and LiveKit (Python + JS) HTTP/WebSocket TTFB benchmark scripts and docs.
  • Introduced git submodules for Pipecat and LiveKit Agents repos, plus top-level integrations index.

Reviewed changes

Copilot reviewed 27 out of 32 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
integrations/pipecat/pipecat-quickstart/pyproject.toml Adds UV project definition for the Pipecat quickstart.
integrations/pipecat/pipecat-quickstart/env.example Provides example env vars for required API keys.
integrations/pipecat/pipecat-quickstart/bot.py Implements a Pipecat voice bot example with STT/LLM/TTS and timestamp debugging.
integrations/pipecat/pipecat-quickstart/README.md Documents local setup and running instructions for the Pipecat quickstart.
integrations/pipecat/pipecat Adds Pipecat as a git submodule.
integrations/pipecat/benchmarks/benchmark_websocket_ttfb.py Adds Pipecat WebSocket TTFB benchmark script.
integrations/pipecat/benchmarks/benchmark_streaming_ttfb.py Adds Pipecat HTTP/streaming TTFB benchmark script.
integrations/pipecat/benchmarks/README.md Documents running Pipecat benchmark scripts.
integrations/livekit/python/quickstart/test_inworld_voice_agent.py Adds a LiveKit Python test agent for Inworld TTS plugin development.
integrations/livekit/python/quickstart/README.md Documents running the LiveKit Python quickstart test agent.
integrations/livekit/python/quickstart/.env-example Provides example LiveKit Python quickstart environment variables.
integrations/livekit/python/benchmarks/benchmark_websocket_ttfb.py Adds LiveKit Python WebSocket TTFB benchmark script.
integrations/livekit/python/benchmarks/benchmark_http_ttfb.py Adds LiveKit Python HTTP TTFB benchmark script.
integrations/livekit/python/benchmarks/README.md Documents running LiveKit Python benchmark scripts.
integrations/livekit/python/benchmarks/.env-example Provides example env vars for LiveKit Python benchmarks.
integrations/livekit/python/agents Adds LiveKit Agents (Python) as a git submodule.
integrations/livekit/js/quickstart/test_agent.ts Adds a LiveKit JS quickstart test agent for Inworld TTS.
integrations/livekit/js/quickstart/package.json Adds package manifest for the LiveKit JS quickstart.
integrations/livekit/js/quickstart/README.md Documents LiveKit JS quickstart setup and usage.
integrations/livekit/js/quickstart/.env-example Provides example env vars for LiveKit JS quickstart.
integrations/livekit/js/benchmarks/package.json Adds package manifest for LiveKit JS benchmarks.
integrations/livekit/js/benchmarks/benchmark_websocket_ttfb.ts Adds LiveKit JS WebSocket TTFB benchmark script.
integrations/livekit/js/benchmarks/benchmark_http_ttfb.ts Adds LiveKit JS HTTP TTFB benchmark script.
integrations/livekit/js/benchmarks/README.md Documents running LiveKit JS benchmark scripts.
integrations/livekit/js/agents-js Adds LiveKit Agents (JS) as a git submodule.
integrations/README.md Adds an index README linking to quickstarts and benchmarks.
.gitmodules Registers the new git submodules for Pipecat and LiveKit Agents.
.gitignore Ignores generated benchmark audio output directory.
Files not reviewed (3)
  • integrations/livekit/js/benchmarks/package-lock.json: Language not supported
  • integrations/livekit/js/benchmarks/pnpm-lock.yaml: Language not supported
  • integrations/livekit/js/quickstart/pnpm-lock.yaml: Language not supported
Comments suppressed due to low confidence (2)

integrations/pipecat/benchmarks/benchmark_streaming_ttfb.py:507

  • The --iterations help text says the default is 50, but default=20. Update the help string so it matches the actual default value.
        "-n",
        "--iterations",
        type=int,
        default=20,
        help="Number of benchmark iterations to run (default: 50)",
    )

integrations/livekit/js/benchmarks/benchmark_websocket_ttfb.ts:371

  • The --debug option is parsed but not used anywhere in the script. Either wire it up (e.g., set initializeLogger({ level: 'debug' }) or enable more verbose output) or remove the option to avoid confusion.
  const { values } = parseArgs({
    options: {
      'token-delay': { type: 'string', default: '50' },
      text: { type: 'string' },
      iterations: { type: 'string', short: 'n', default: '1' },
      services: { type: 'string', default: 'all' },
      'no-save-audio': { type: 'boolean', default: false },
      debug: { type: 'boolean', default: false },
    },
  });

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +248 to +262
async def _check_audio_done(self):
"""Check if audio has stopped arriving and signal completion."""
# Wait for first audio to arrive
while self.first_audio_time is None:
await asyncio.sleep(0.1)

# Now wait for audio to stop (no new audio for 2 seconds)
while True:
await asyncio.sleep(0.5)
if self.last_audio_time and (time.time() - self.last_audio_time) > 2.0:
logger.info(f"🏁 [{self.service_name}] Audio stream complete")
# Save audio files when done
self.save_audio_files()
self._done_event.set()
break

Copilot AI Mar 2, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This completion logic can hang forever if no audio ever arrives (e.g., auth failure, provider error, or pipeline ends early). wait_for_completion() will block indefinitely because _done_event is never set. Add a timeout or an alternate completion path (e.g., set _done_event on EndFrame/terminal frames, or after N seconds without receiving any TTSAudioRawFrame).

Copilot uses AI. Check for mistakes.
Comment on lines +225 to +238
async def _check_audio_done(self):
"""Check if audio has stopped arriving and signal completion."""
# Wait for first audio to arrive
while self.first_audio_time is None:
await asyncio.sleep(0.1)

# Now wait for audio to stop (no new audio for 2 seconds)
while True:
await asyncio.sleep(0.5)
if self.last_audio_time and (time.time() - self.last_audio_time) > 2.0:
# Save audio files when done
self.save_audio_files()
self._done_event.set()
break

Copilot AI Mar 2, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as the WebSocket benchmark: this will wait forever if no audio frames arrive, causing the benchmark run to hang. Consider setting _done_event when an EndFrame is observed (or when the pipeline is cancelled), and/or add a maximum wait timeout for the initial audio.

Copilot uses AI. Check for mistakes.
Comment on lines +548 to +567
service_configs = {
"inworld": {
"name": "Inworld HTTP",
"create_fn": create_inworld_http_tts,
"api_key_env": "BASE64_SECRET_KEY",
"extra_env": {},
},
"elevenlabs": {
"name": "ElevenLabs HTTP",
"create_fn": create_elevenlabs_http_tts,
"api_key_env": "ELEVEN_API_KEY",
"extra_env": {},
},
"cartesia": {
"name": "Cartesia HTTP",
"create_fn": create_cartesia_http_tts,
"api_key_env": "CARTESIA_API_KEY",
"extra_env": {},
},
}

Copilot AI Mar 2, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Inworld HTTP config reads the API key from BASE64_SECRET_KEY, but the user-facing error message (and the other benchmark scripts/READMEs in this PR) instruct using INWORLD_API_KEY. This mismatch will cause Inworld to be skipped even when INWORLD_API_KEY is set. Align on a single env var name (either change api_key_env to INWORLD_API_KEY or update the messaging/docs consistently).

Copilot uses AI. Check for mistakes.

if not available_services:
print("No services available to benchmark. Please set the required API keys:")
print(" - INWORLD_API_KEY for Inworld HTTP")

Copilot AI Mar 2, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Inworld HTTP config reads the API key from BASE64_SECRET_KEY, but the user-facing error message (and the other benchmark scripts/READMEs in this PR) instruct using INWORLD_API_KEY. This mismatch will cause Inworld to be skipped even when INWORLD_API_KEY is set. Align on a single env var name (either change api_key_env to INWORLD_API_KEY or update the messaging/docs consistently).

Suggested change
print(" - INWORLD_API_KEY for Inworld HTTP")
print(" - BASE64_SECRET_KEY for Inworld HTTP")

Copilot uses AI. Check for mistakes.
Comment on lines +35 to +39
console.log('[Inworld TTS] Configuration:');
console.log(` - Base URL: ${baseURL}`);
console.log(` - WebSocket URL: ${wsURL}`);
console.log(` - API Key: ${apiKey ? apiKey.substring(0, 8) + '...' : 'NOT SET'}`);
console.log(` - Voice: ${process.env.INWORLD_VOICE || 'Alex'}`);

Copilot AI Mar 2, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Logging even a partial API key can leak credentials into CI logs, crash reports, or shared terminals. Prefer logging only whether the key is set (e.g., API Key: SET/NOT SET) and avoid printing any part of the secret.

Copilot uses AI. Check for mistakes.
"@livekit/agents": "link:../agents-js/agents",
"@livekit/agents-plugin-livekit": "link:../agents-js/plugins/livekit",
"@livekit/agents-plugin-silero": "link:../agents-js/plugins/silero",
"@livekit/rtc-node": "link:../agents-js/node_modules/.pnpm/@livekit+rtc-node@0.13.24/node_modules/@livekit/rtc-node",

Copilot AI Mar 2, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This dependency points to a pnpm store path inside another workspace (node_modules/.pnpm/...), which is highly environment-specific and will break for most users. Use a normal semver dependency (e.g. ^0.13.24) or link to the package in the repo in a stable way (e.g. link:../agents-js/node_modules/@livekit/rtc-node if intentionally vendored, or preferably just a version range).

Suggested change
"@livekit/rtc-node": "link:../agents-js/node_modules/.pnpm/@livekit+rtc-node@0.13.24/node_modules/@livekit/rtc-node",
"@livekit/rtc-node": "^0.13.24",

Copilot uses AI. Check for mistakes.
Cool-SL and others added 3 commits March 12, 2026 13:11
* finalize model choices and change 11lab voice id, change websocket default sentence

* improved pipecat benchmark to reuse the same connection

* fix pipecat benchmark to not prematurely start next turn

* reduce intra iteration delay to 0.5s
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants