Skip to content

Conversation

@sunghyunjun
Copy link

@sunghyunjun sunghyunjun commented Oct 13, 2025

Summary

Adds Typecast TTS plugin for creating lifelike speech with unique character voices and precise emotion control.

About Typecast

Typecast is a text-to-speech service that offers 180+ unique AI voices with distinct personalities across multiple languages. The Typecast API enables precise customization of tone, emotion, speed, and pitch, allowing developers to create rich, expressive audio that brings conversational AI to life. With ultra-fast synthesis speeds, it can turn hours of content into high-quality audio in minutes.

Key Features

Character Voices & Emotion Control

  • 180+ unique voices with distinct personalities
  • Multi-language support: 30+ languages (ISO 639-3 codes)
  • Fine-tune emotions with presets: normal, happy, sad, angry, etc.
  • Adjustable emotion intensity: 0.0 - 2.0 for precise expression
  • Creates rich, expressive audio for natural conversations

Audio Customization

  • Precise control: pitch, tempo, volume adjustments
  • Reproducible synthesis with seed parameter
  • High-quality output: 44.1kHz WAV/MP3 format

Implementation

  • Follows standard LiveKit plugin patterns (consistent with ElevenLabs, Cartesia, OpenAI)

Testing

  • Integration tests added to tests/test_tts.py
  • Docker test environment configured
  • Verified with actual API calls

Files Changed

Plugin: livekit-plugins/livekit-plugins-typecast/

  • Core implementation with emotion control
  • Voice listing API integration
  • Standard plugin structure (7 files)

Example: examples/other/text-to-speech/typecast_tts.py

  • Basic usage with emotion presets
  • Voice discovery example
  • Audio customization demos

Configuration:

  • pyproject.toml: workspace configuration
  • tests/docker-compose.yml: test environment
  • tests/test_tts.py: test integration
  • examples/other/text-to-speech/requirements.txt

Summary by CodeRabbit

  • New Features

    • Added Typecast text-to-speech integration with emotional synthesis support (presets and intensity control).
    • Support for audio adjustments including volume, pitch, and tempo.
    • Multiple audio format and language support with voice management capabilities.
    • New example demonstrating synthesis scenarios.
  • Tests

    • Added Typecast TTS backend to test suite.
  • Chores

    • Added Typecast plugin dependency and updated test environment configuration.

✏️ Tip: You can customize this high-level summary in your review settings.

@CLAassistant
Copy link

CLAassistant commented Oct 13, 2025

CLA assistant check
All committers have signed the CLA.

@sunghyunjun sunghyunjun force-pushed the feat/typecast-tts-plugin branch from 0d2a125 to 03c6bf6 Compare January 8, 2026 03:10
@sunghyunjun
Copy link
Author

Update (2026-01-08): Rebasing done onto latest main.

  • Updated implementation to match current plugin patterns
  • Adjusted integration tests + docker env where needed
  • CI is green (let me know if you'd like additional coverage)

@sunghyunjun
Copy link
Author

Hi @theomonnom @chenghao-mou 👋

I rebased this PR onto the latest main today and aligned it with the current plugin and test patterns.
All integration tests are passing.

For context, this adds a Typecast TTS plugin following the same structure as existing providers (e.g. ElevenLabs, Cartesia),
with a focus on fine-grained emotion control (including adjustable intensity) and multilingual voices.

FYI: Typecast is a TTS service developed by the company I work at, and I’m committed to maintaining this plugin long-term.

Could you advise on the preferred path to land this?

  • A) merge as an in-tree plugin under livekit-plugins, or
  • B) keep it as an external/community plugin

Happy to adapt naming, env vars, or structure based on your guidance. Thanks!

@sunghyunjun sunghyunjun force-pushed the feat/typecast-tts-plugin branch from 27a4a08 to 4f8272b Compare January 15, 2026 01:49
@sunghyunjun
Copy link
Author

Gentle bump @theomonnom — just looking for a quick direction on in-tree merge vs external plugin.
Once I have that, I can finalize any remaining tweaks immediately.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 30, 2026

📝 Walkthrough

Walkthrough

This pull request introduces a complete Typecast Text-to-Speech plugin for LiveKit, including the plugin implementation with voice discovery and synthesis capabilities, supporting models and type definitions, example code demonstrating various synthesis scenarios, and updated test infrastructure to integrate the new backend.

Changes

Cohort / File(s) Summary
Typecast Plugin Core Implementation
livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/__init__.py, tts.py, models.py, log.py, version.py
Introduces the complete Typecast TTS backend with TTS and ChunkedStream classes supporting voice synthesis, emotional control via PromptOptions, audio adjustments via OutputOptions, voice discovery, API integration, and error handling. Includes model/type definitions (Voice, PromptOptions, OutputOptions, AudioFormat, TTSLanguages, TTSModels) and module logging setup.
Plugin Package Configuration
livekit-plugins/livekit-plugins-typecast/pyproject.toml, README.md
Adds project metadata, build configuration using Hatchling, dependency declarations, and setup instructions for the Typecast plugin package, including environment variable prerequisites.
Workspace & Test Integration
pyproject.toml, tests/test_tts.py, tests/docker-compose.yml
Registers the typecast plugin as a workspace source, adds typecast TTS backend to the test matrix with API proxy configuration, and configures environment variables for test execution.
Example & Dependencies
examples/other/text-to-speech/typecast_tts.py, requirements.txt
Provides a demonstration agent executing five synthesis scenarios showcasing basic synthesis, emotion presets (happy/sad), audio adjustments (volume/pitch/tempo), and reproducible synthesis with seed control.

Sequence Diagram(s)

sequenceDiagram
    participant Agent as LiveKit Agent
    participant TTS as Typecast TTS
    participant API as Typecast API
    participant Room as LiveKit Room
    
    Agent->>TTS: synthesize(text, conn_options)
    TTS->>TTS: apply PromptOptions & OutputOptions
    TTS->>API: POST /synthesize (with payload)
    API-->>TTS: audio stream (chunks)
    TTS->>TTS: map format to MIME type
    TTS->>Room: stream audio chunks via AudioTrack
    Note over TTS,Room: Live audio playback
    TTS-->>Agent: ChunkedStream complete
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • theomonnom
  • chenghao-mou
  • davidzhao

Poem

🐰 A Typecast spell we weave today,
With voices eager, emotions at play,
From API whispers to LiveKit's ear,
Synthesized speech, crystal and clear!
Happy, sad, or pitched just right,
The rabbit's TTS gift—takes flight! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 35.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding a Typecast TTS plugin to livekit-plugins. It is concise, clear, and directly related to the primary objective of the PR.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

🧹 Recent nitpick comments
livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/models.py (2)

69-87: Consider adding explicit return type for strict mypy.

The to_dict() method returns an untyped dict. For strict mypy compliance, consider using a more specific return type.

♻️ Suggested refinement
-    def to_dict(self) -> dict:
+    def to_dict(self) -> dict[str, str | float]:
         return {
             "emotion_preset": self.emotion_preset,
             "emotion_intensity": self.emotion_intensity,
         }

As per coding guidelines: Run mypy type checker in strict mode.


89-112: Consider adding explicit return type for strict mypy.

Same as PromptOptions.to_dict(), the return type could be more specific for strict mypy compliance.

♻️ Suggested refinement
-    def to_dict(self) -> dict:
+    def to_dict(self) -> dict[str, int | float | str]:
         return {
             "volume": self.volume,
             "audio_pitch": self.audio_pitch,
             "audio_tempo": self.audio_tempo,
             "audio_format": self.audio_format,
         }

As per coding guidelines: Run mypy type checker in strict mode.

livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/tts.py (1)

143-146: Consider using URL path joining instead of string replace.

The string replace approach self._opts.base_url.replace("/text-to-speech", "") is fragile—if base_url doesn't contain /text-to-speech or contains it multiple times, this could produce unexpected results.

♻️ Suggested refinement using urllib
+from urllib.parse import urljoin
+
+# In list_voices method:
-        # Extract base URL from text-to-speech endpoint
-        base_url = self._opts.base_url.replace("/text-to-speech", "")
-        url = f"{base_url}/voices"
+        # Build voices URL relative to base
+        url = self._opts.base_url.rsplit("/text-to-speech", 1)[0] + "/voices"

Or consider storing a separate api_base (e.g., https://api.typecast.ai/v1) rather than the full endpoint URL, allowing cleaner path construction.

📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ed10b26 and 6315704.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (13)
  • examples/other/text-to-speech/requirements.txt
  • examples/other/text-to-speech/typecast_tts.py
  • livekit-plugins/livekit-plugins-typecast/README.md
  • livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/__init__.py
  • livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/log.py
  • livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/models.py
  • livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/py.typed
  • livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/tts.py
  • livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/version.py
  • livekit-plugins/livekit-plugins-typecast/pyproject.toml
  • pyproject.toml
  • tests/docker-compose.yml
  • tests/test_tts.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/test_tts.py
  • livekit-plugins/livekit-plugins-typecast/README.md
🧰 Additional context used
📓 Path-based instructions (1)
**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

**/*.py: Format code with ruff
Run ruff linter and auto-fix issues
Run mypy type checker in strict mode
Maintain line length of 100 characters maximum
Ensure Python 3.9+ compatibility
Use Google-style docstrings

Files:

  • livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/log.py
  • livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/version.py
  • livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/models.py
  • livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/__init__.py
  • livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/tts.py
  • examples/other/text-to-speech/typecast_tts.py
🧠 Learnings (1)
📚 Learning: 2026-01-16T07:44:56.353Z
Learnt from: CR
Repo: livekit/agents PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-16T07:44:56.353Z
Learning: Follow the Plugin System pattern where plugins in livekit-plugins/ are separate packages registered via the Plugin base class

Applied to files:

  • pyproject.toml
  • examples/other/text-to-speech/requirements.txt
🧬 Code graph analysis (3)
livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/models.py (2)
livekit-plugins/livekit-plugins-hume/livekit/plugins/hume/tts.py (1)
  • AudioFormat (68-73)
livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/tts.py (1)
  • model (112-113)
livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/__init__.py (3)
livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/models.py (3)
  • OutputOptions (90-112)
  • PromptOptions (70-86)
  • Voice (52-66)
livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/tts.py (1)
  • TTS (55-256)
livekit-agents/livekit/agents/plugin.py (2)
  • Plugin (13-56)
  • register_plugin (31-36)
livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/tts.py (4)
livekit-agents/livekit/agents/_exceptions.py (3)
  • APIConnectionError (84-88)
  • APIStatusError (45-81)
  • APITimeoutError (91-95)
livekit-agents/livekit/agents/utils/misc.py (2)
  • is_given (25-26)
  • shortuuid (21-22)
livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/models.py (5)
  • OutputOptions (90-112)
  • PromptOptions (70-86)
  • Voice (52-66)
  • to_dict (82-86)
  • to_dict (106-112)
livekit-agents/livekit/agents/utils/http_context.py (1)
  • http_session (40-51)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: unit-tests
  • GitHub Check: type-check (3.13)
  • GitHub Check: type-check (3.9)
🔇 Additional comments (27)
tests/docker-compose.yml (1)

63-64: Looks good for Typecast test wiring.

The new environment variable and host mapping line up with the Typecast backend support in tests.

Also applies to: 84-84

livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/version.py (1)

15-15: Version constant is clear and standard.

examples/other/text-to-speech/requirements.txt (1)

6-6: Dependency addition for the example looks fine.

livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/log.py (1)

1-3: Logger setup is clean and consistent.

pyproject.toml (1)

54-54: Workspace source entry looks good.

livekit-plugins/livekit-plugins-typecast/pyproject.toml (1)

1-43: Packaging metadata and build config look solid.

livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/__init__.py (3)

15-45: Clear module docs and public exports.

The docstring and explicit __all__ keep the public API surface well-defined.


47-57: Plugin wiring and logger injection look consistent.


59-66: Docs cleanup for non-exported symbols is tidy.

examples/other/text-to-speech/typecast_tts.py (5)

1-14: LGTM!

Clean imports and logger setup. The use of load_dotenv() at module level is appropriate for an example script.


16-53: LGTM!

The entrypoint now has proper return type annotation and Google-style docstring. The try/finally pattern ensures the TTS client is properly closed. Voice listing with graceful error handling is a good pattern for examples.


54-69: LGTM!

Audio track setup and basic synthesis demonstration are well-structured.


72-98: LGTM!

Good demonstration of emotional expression with PromptOptions. The happy and sad emotion examples clearly show the plugin's emotion control capabilities.


100-143: LGTM!

Examples 4 and 5 effectively demonstrate audio adjustments via OutputOptions and reproducible synthesis with seeds. The cleanup in the finally block ensures proper resource management.

livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/models.py (2)

1-49: LGTM!

Well-defined type aliases and constants. The use of Literal types for TTSModels, AudioFormat, and TTSLanguages provides good type safety and is consistent across the module.


51-67: LGTM!

Clean dataclass definition with proper Google-style docstring documenting all attributes.

livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/tts.py (11)

1-40: LGTM!

Clean imports and well-defined constants. The NUM_CHANNELS = 1 and API constants are appropriately scoped at the module level.


42-53: LGTM!

The _TTSOptions dataclass cleanly encapsulates all configuration options. Using a dataclass here enables the replace() function in ChunkedStream for creating immutable copies.


55-109: LGTM!

Well-documented constructor with proper API key validation. The pattern of falling back to environment variables while requiring the key to be present is a good practice.


111-122: LGTM!

Simple property accessors and session management. The _ensure_session() pattern leverages the framework's http_context.http_session() appropriately.


147-196: LGTM!

Solid error handling in list_voices(). The try/except structure properly maps aiohttp exceptions to the appropriate API error types, and re-raises already-handled exceptions.


198-234: LGTM!

The update_options() method cleanly handles partial updates using the is_given() pattern, consistent with the framework's NOT_GIVEN sentinel approach.


236-256: LGTM!

Simple factory method returning a ChunkedStream for synthesis.


259-276: LGTM!

Good use of replace(tts._opts) to create a snapshot of options at synthesis time, preventing mid-synthesis option mutations from affecting the current request.


278-313: LGTM!

Payload construction and debug logging are well-structured. The conditional addition of optional parameters (language, seed) keeps the payload clean.


315-365: LGTM!

The _run method properly addresses the previous review concerns:

  • MIME type is correctly mapped based on audio_format (mp3 → audio/mpeg, wav → audio/wav)
  • Sample rate is hardcoded to 44100 Hz to match Typecast API's fixed output rate
  • Chunked streaming with 1024-byte chunks is appropriate

367-379: LGTM!

Consistent error handling pattern that mirrors list_voices(), properly converting aiohttp exceptions to framework API errors.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@examples/other/text-to-speech/typecast_tts.py`:
- Around line 16-127: Add a Google-style docstring and an explicit return type
to the entrypoint (change async def entrypoint(job: JobContext) to async def
entrypoint(job: JobContext) -> None) and ensure the Typecast client is closed to
avoid leaking aiohttp sessions by wrapping the existing logic in a try/finally
(create tts = typecast.TTS(...) before the try, keep current try/except for
list_voices and the rest in the try block, and in the finally call await
tts.close()) so the tts client is always closed even on errors; reference
symbols: entrypoint, tts, typecast.TTS, and tts.close().

In `@livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/tts.py`:
- Around line 285-299: The code builds the API payload with user-provided
options but later uses self._opts.sample_rate (user-controlled) to initialize
the output emitter, causing a metadata mismatch; update the emitter
initialization to always use sample_rate=44100 (hardcode 44100 Hz) instead of
self._opts.sample_rate so the output metadata matches Typecast v1's fixed 44,100
Hz output (refer to the payload construction and the use of
self._opts.sample_rate in this module).
- Around line 339-346: The emitter's MIME type is hardcoded to "audio/wav" but
must reflect output_options.audio_format; update the call to
output_emitter.initialize (in function/method where request_id, sample_rate,
num_channels are set) to set mime_type dynamically by mapping
output_options.audio_format == "mp3" -> "audio/mpeg", "wav" -> "audio/wav" (and
fall back to a safe default or raise if unsupported). Ensure you reference
output_options.audio_format when constructing the mime_type argument so the
declared MIME matches the Typecast API response.
🧹 Nitpick comments (2)
livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/log.py (1)

1-3: Add a short module docstring for consistency.
Optional but aligns with the docstring guideline.

Suggested change
+"""Logging utilities for the Typecast plugin."""
 import logging
 
 logger = logging.getLogger("livekit.plugins.typecast")

As per coding guidelines: Use Google-style docstrings.

tests/test_tts.py (1)

253-257: Prefer the shared DEFAULT_VOICE_ID instead of a hard-coded literal.

This keeps the test aligned with the plugin constant and avoids drift if the default changes.

🔧 Proposed change
-            "tts": typecast.TTS(
-                voice=os.getenv("TYPECAST_VOICE_ID", "tc_62a8975e695ad26f7fb514d1")
-            ),
+            "tts": typecast.TTS(
+                voice=os.getenv("TYPECAST_VOICE_ID", typecast.DEFAULT_VOICE_ID)
+            ),
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3ee8e34 and f811c2b.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (14)
  • examples/other/text-to-speech/requirements.txt
  • examples/other/text-to-speech/typecast_tts.py
  • livekit-agents/livekit/agents/cli/cli.py
  • livekit-plugins/livekit-plugins-typecast/README.md
  • livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/__init__.py
  • livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/log.py
  • livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/models.py
  • livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/py.typed
  • livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/tts.py
  • livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/version.py
  • livekit-plugins/livekit-plugins-typecast/pyproject.toml
  • pyproject.toml
  • tests/docker-compose.yml
  • tests/test_tts.py
🧰 Additional context used
📓 Path-based instructions (1)
**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

**/*.py: Format code with ruff
Run ruff linter and auto-fix issues
Run mypy type checker in strict mode
Maintain line length of 100 characters maximum
Ensure Python 3.9+ compatibility
Use Google-style docstrings

Files:

  • livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/version.py
  • examples/other/text-to-speech/typecast_tts.py
  • livekit-agents/livekit/agents/cli/cli.py
  • livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/log.py
  • tests/test_tts.py
  • livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/models.py
  • livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/tts.py
  • livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/__init__.py
🧠 Learnings (3)
📓 Common learnings
Learnt from: CR
Repo: livekit/agents PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-16T07:44:56.353Z
Learning: Implement Model Interface Pattern for STT, TTS, LLM, and Realtime models with provider-agnostic interfaces, fallback adapters for resilience, and stream adapters for different streaming patterns
📚 Learning: 2026-01-16T07:44:56.353Z
Learnt from: CR
Repo: livekit/agents PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-16T07:44:56.353Z
Learning: Follow the Plugin System pattern where plugins in livekit-plugins/ are separate packages registered via the Plugin base class

Applied to files:

  • examples/other/text-to-speech/requirements.txt
  • pyproject.toml
📚 Learning: 2026-01-22T03:28:16.289Z
Learnt from: longcw
Repo: livekit/agents PR: 4563
File: livekit-agents/livekit/agents/beta/tools/end_call.py:65-65
Timestamp: 2026-01-22T03:28:16.289Z
Learning: In code paths that check capabilities or behavior of the LLM processing the current interaction, prefer using the activity's LLM obtained via ctx.session.current_agent._get_activity_or_raise().llm instead of ctx.session.llm. The session-level LLM may be a fallback and not reflect the actual agent handling the interaction. Use the activity LLM to determine capabilities and to make capability checks or feature toggles relevant to the current processing agent.

Applied to files:

  • livekit-agents/livekit/agents/cli/cli.py
🧬 Code graph analysis (3)
tests/test_tts.py (1)
livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/tts.py (1)
  • TTS (55-256)
livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/models.py (2)
livekit-plugins/livekit-plugins-hume/livekit/plugins/hume/tts.py (1)
  • AudioFormat (68-73)
livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/tts.py (1)
  • model (112-113)
livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/tts.py (3)
livekit-agents/livekit/agents/_exceptions.py (3)
  • APIConnectionError (84-88)
  • APIStatusError (45-81)
  • APITimeoutError (91-95)
livekit-agents/livekit/agents/types.py (1)
  • APIConnectOptions (54-88)
livekit-agents/livekit/agents/utils/misc.py (2)
  • is_given (25-26)
  • shortuuid (21-22)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: unit-tests
  • GitHub Check: type-check (3.13)
🔇 Additional comments (9)
livekit-plugins/livekit-plugins-typecast/README.md (1)

1-15: Clear and helpful README.

livekit-agents/livekit/agents/cli/cli.py (4)

724-726: Formatting improvement looks good.


980-982: Readable prompt formatting.


989-991: Shortcut rendering update is clear.


1167-1183: Nice UX improvement for JSON outputs.

examples/other/text-to-speech/requirements.txt (1)

6-6: Dependency addition looks good.

livekit-plugins/livekit-plugins-typecast/livekit/plugins/typecast/version.py (1)

1-15: Version module is straightforward.

tests/docker-compose.yml (1)

63-64: Test environment wiring looks consistent.

Also applies to: 84-84

pyproject.toml (1)

49-49: Workspace source addition is correct.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

sunghyunjun and others added 7 commits January 30, 2026 21:24
- Add emotion control with presets and intensity adjustment
- Support 30+ languages (ISO 639-3)
- Audio customization support
- Include standard LiveKit agent example
- Add Docker test configuration
Address PR review feedback to improve consistency with other TTS plugins.

Changes:
- Add DEFAULT_VOICE_ID constant (Olivia voice)
- Add Voice dataclass for voice metadata
- Make voice parameter optional with default value
- Implement list_voices() method to query available voices
- Add voice listing example to demo script
- Export Voice and DEFAULT_VOICE_ID in public API

The plugin now follows the same pattern as ElevenLabs, providing:
- Default voice for quick start
- Voice discovery through list_voices()
- Improved user experience
- Change mime_type from 'audio/pcm' to 'audio/wav' to leverage AudioEmitter's built-in WAV header parsing
- Remove manual 44-byte WAV header stripping (AudioEmitter handles this automatically)
- Update livekit-agents dependency from >=1.2.14 to >=1.3.10
…string and improved error handling

- Added a comprehensive docstring to the entrypoint function, outlining its purpose and arguments.
- Improved error handling when listing available voices, logging warnings for exceptions.
- Streamlined the synthesis examples for emotional expression and audio adjustments, ensuring clarity and consistency in the demonstration flow.
- Implemented dynamic mapping of audio formats to MIME types, supporting 'mp3' and 'wav'.
- Updated output emitter initialization to use the appropriate MIME type based on user options.
- Ensured consistent sample rate of 44,100 Hz for Typecast v1 API outputs.
@hmmhmmhm hmmhmmhm force-pushed the feat/typecast-tts-plugin branch from ed10b26 to 6315704 Compare January 30, 2026 12:24
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.

3 participants