Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -148,14 +148,13 @@ def __init__(
min_turn_silence: Minimum silence in ms before a confident end-of-turn is finalized.
min_end_of_turn_silence_when_confident: Deprecated. Use min_turn_silence instead.
continuous_partials: Whether to emit additional partial transcripts during long
turns at a steady ~3 second cadence. By default, partials are emitted at
two points: one at 750 ms after turn start (configurable via
`interruption_delay`), and one each time silence exceeds
`min_turn_silence` without ending the turn. When enabled (default in
LiveKit; AssemblyAI server defaults to False), additional partials covering
the full turn transcript are emitted approximately every 3 seconds while
speech continues, on top of those baseline partials. Only supported with
the Universal-3 Pro family models.
turns at a steady ~3 second cadence, on top of the baseline partials
(one at 750 ms after turn start, configurable via `interruption_delay`,
and one each time silence exceeds `min_turn_silence` without ending the
turn). Leave unset to use AssemblyAI's server defaults: enabled, except
when `speaker_labels` is on, where the server disables it so turns break
cleanly at speaker changes. Only supported with the Universal-3 Pro
family models.
interruption_delay: How soon the first early partial is emitted, in ms.
Range 0–1000, default 500. Lower values produce faster time-to-first-token
for barge-in; higher values produce more confident first partials. Only
Expand Down Expand Up @@ -239,12 +238,6 @@ def __init__(
f"{', '.join(_U3_PRO_MODELS)} models."
)

# LiveKit defaults continuous_partials to True (vs. AssemblyAI's server default of
# False) for steady-cadence partials. This parameter is only supported for
# the Universal-3 Pro family, enforced by the validation above.
if not is_given(continuous_partials) and model in _U3_PRO_MODELS:
continuous_partials = True

self._base_url = base_url
assemblyai_api_key = api_key if is_given(api_key) else os.environ.get("ASSEMBLYAI_API_KEY")
if not assemblyai_api_key:
Expand Down
47 changes: 22 additions & 25 deletions tests/test_plugin_assemblyai_stt.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,12 +192,8 @@ async def test_start_time_has_default_before_plugin_override():


async def test_continuous_partials_default():
"""Test continuous_partials is not set by default for a non-u3-rt-pro-family model.

(The plugin default model is universal-3-5-pro, a u3-rt-pro-family model that
defaults continuous_partials to True — covered by
test_universal_3_5_pro_defaults_continuous_partials_true.)
"""
"""Test continuous_partials is not set by default so AssemblyAI's server defaults
apply (enabled, except when speaker_labels is on)."""
from livekit.plugins.assemblyai import STT

stt = STT(api_key="test-key", model="universal-streaming-english")
Expand Down Expand Up @@ -252,30 +248,29 @@ async def test_continuous_partials_update():
assert stt._opts.continuous_partials is True


async def test_continuous_partials_defaults_to_true_for_u3_rt_pro():
"""Test continuous_partials defaults to True when model is u3-rt-pro (LiveKit-only
default; AssemblyAI server defaults to False)."""
async def test_continuous_partials_unset_by_default_for_u3_rt_pro():
"""continuous_partials is left unset for u3-rt-pro so AssemblyAI's server defaults
apply (enabled, but disabled by the server when speaker_labels is on)."""
from livekit.plugins.assemblyai import STT

stt = STT(api_key="test-key", model="u3-rt-pro")
assert stt._opts.continuous_partials is True
assert stt._opts.continuous_partials is NOT_GIVEN


async def test_continuous_partials_explicit_false_overrides_livekit_default():
"""Test explicit continuous_partials=False overrides the LiveKit-only True default."""
async def test_continuous_partials_explicit_false():
"""Test explicit continuous_partials=False is preserved."""
from livekit.plugins.assemblyai import STT

stt = STT(api_key="test-key", model="u3-rt-pro", continuous_partials=False)
assert stt._opts.continuous_partials is False


async def test_continuous_partials_update_from_default():
"""Test continuous_partials can be updated via update_options away from LiveKit default."""
"""Test continuous_partials can be set via update_options when unset at construction."""
from livekit.plugins.assemblyai import STT

# LiveKit defaults this to True for u3-rt-pro
stt = STT(api_key="test-key", model="u3-rt-pro")
assert stt._opts.continuous_partials is True
assert stt._opts.continuous_partials is NOT_GIVEN

stt.update_options(continuous_partials=False)
assert stt._opts.continuous_partials is False
Expand Down Expand Up @@ -412,7 +407,7 @@ def _fake_create_task(coro, *args, **kwargs):
#
# u3-rt-pro-beta-1 shares all u3-rt-pro behavior, so the u3-pro-gated params
# (prompt, agent_context, previous_context_n_turns, continuous_partials,
# interruption_delay) are accepted with it, and continuous_partials defaults to True.
# interruption_delay) are accepted with it.
# ---------------------------------------------------------------------------


Expand All @@ -422,8 +417,8 @@ async def test_u3_rt_pro_beta_1_accepted():

stt = STT(api_key="test-key", model="u3-rt-pro-beta-1")
assert stt._opts.speech_model == "u3-rt-pro-beta-1"
# continuous_partials defaults to True for the u3-rt-pro family
assert stt._opts.continuous_partials is True
# continuous_partials is left unset so AssemblyAI's server defaults apply
assert stt._opts.continuous_partials is NOT_GIVEN


async def test_u3_rt_pro_beta_1_accepts_u3_pro_params():
Expand Down Expand Up @@ -557,12 +552,13 @@ async def test_universal_3_5_pro_accepts_u3_pro_params():
assert stt._opts.interruption_delay == 300


async def test_universal_3_5_pro_defaults_continuous_partials_true():
"""continuous_partials defaults to True for universal-3-5-pro (u3-rt-pro family)."""
async def test_universal_3_5_pro_leaves_continuous_partials_unset():
"""continuous_partials is left unset for universal-3-5-pro so AssemblyAI's server
defaults apply (enabled, but disabled by the server when speaker_labels is on)."""
from livekit.plugins.assemblyai import STT

stt = STT(api_key="test-key", model="universal-3-5-pro")
assert stt._opts.continuous_partials is True
assert stt._opts.continuous_partials is NOT_GIVEN


# ---------------------------------------------------------------------------
Expand Down Expand Up @@ -717,13 +713,14 @@ async def test_voice_focus_allowed_for_all_u3_pro_family_models():
assert stt._opts.voice_focus == "far-field"


async def test_default_model_defaults_continuous_partials_true():
"""A bare STT() (relying on the default model) defaults continuous_partials to True,
tying the default-model choice to its u3-rt-pro-family behavior."""
async def test_default_model_leaves_continuous_partials_unset():
"""A bare STT() (relying on the default model) leaves continuous_partials unset so
AssemblyAI's server defaults apply (enabled, but disabled by the server when
speaker_labels is on)."""
from livekit.plugins.assemblyai import STT

stt = STT(api_key="test-key")
assert stt._opts.continuous_partials is True
assert stt._opts.continuous_partials is NOT_GIVEN


# ---------------------------------------------------------------------------
Expand Down
Loading