brief-dress-9950
05/20/2026, 2:59 PMtall-airline-16756
05/20/2026, 2:59 PMtall-airline-16756
05/20/2026, 2:59 PMsmart-turn model into LiveKit cascaded agents.
I do not have documentation that confirms a direct, built‑in integration for that third‑party repo. However, you can likely integrate an external turn‑detection model by having your cascaded agent call the model as an external service and feed its decisions back into the LiveKit agent flow.
To give concrete guidance I need a bit more detail:
• Do you plan to run smart-turn as a hosted HTTP service, a local process, or embed it inside your agent runtime?
• Which LiveKit cascaded agent flow are you using (e.g., realtime transcription → dialog manager → orchestrator)?
• Do you want turn signals to influence speaker handoff/room control, or only to annotate transcripts/events?
With those answers I’ll outline an integration pattern (API endpoints, event wiring, where to insert model calls in the agent pipeline, and example message formats).
, with interactive elementsbrief-dress-9950
05/20/2026, 3:02 PMtall-airline-16756
05/20/2026, 3:02 PMsmart-turn inside your agent runtime so its turn signals control whether the agent speaks.
I can guide you, but I need a few specifics to produce a concrete integration pattern and code sketches:
1. Which runtime/SDK are you using: Python or Node.js?
2. LiveKit Agents package/version you have installed.
3. How will you invoke smart-turn in-process:
◦ imported Python module,
◦ subprocess per utterance,
◦ or an async in-process function called on each STT partial/final?
1. Do you use streaming partial transcripts or only final transcripts? Do you have word-level timestamps?
2. Exact desired agent behaviour when smart-turn signals end-of-user-turn:
◦ immediately cancel agent TTS and speak,
◦ wait N ms for confirmation,
◦ or queue reply and start only after VAD confirms silence?
1. Latency/CPU constraints (e.g., must decisions be <100 ms?)
2. Do you want to replace LiveKit’s built-in turn detector or run alongside it and feed your signal into LiveKit’s turn control?
3. Any constraints on bundling model weights or licensing concerns?
Answering these lets me provide:
• an integration pattern for STT → smart-turn → LLM → TTS,
• example call/invocation code for your runtime,
• recommended confidence thresholds and debounce logic,
• how to wire the turn decision into AgentSession turn handling (Python/Node code sketch). Sources: LiveKit turn detector plugin | LiveKit Documentation | Using a transformer to improve end of turn detection | LiveKit | Turns overview | LiveKit Documentation, with interactive elementsbrief-dress-9950
05/20/2026, 3:04 PMtall-airline-16756
05/20/2026, 3:04 PMsmart-turn inside a Python LiveKit agent (livekit-agents v1.4), call it on every STT partial and final, and replace LiveKit’s built-in turn detector so its signals control agent speaking/turn-taking.
I can provide a concrete integration pattern and code sketch. A couple quick clarifying points before I produce the sample:
• Will you import smart-turn as a Python module in-process (yes/no)?
• Do you have a preferred threshold or debounce behavior for when the agent should start speaking on an end-of-turn signal (e.g., immediate on signal, or wait 100–300 ms to avoid false positives)?
If “yes” to in-process import and you’re okay with a short debounce, I’ll return a focused Python example showing:
1. A custom TurnDetector class that wraps smart-turn and exposes on_partial(text, meta) / on_final(text, meta) methods.
2. How to register that detector in AgentSession(turn_handling=...) to replace the built-in detector.
3. How to call it from the STT callback (partials + finals), convert model outputs to a confidence score, and use a debounce/threshold.
4. How to map the detector decision into agent actions (cancel TTS, yield/start speaking) via the AgentSession turn APIs.
Tell me whether you will import smart-turn in-process and whether you prefer immediate or slightly debounced turn starts, and I’ll post the code example.
, with interactive elementsbrief-dress-9950
05/20/2026, 3:08 PMtall-airline-16756
05/20/2026, 3:08 PMsmart-turn as an in-process turn detector, call it on every STT partial/final, and have its immediate end-of-turn signal control agent speaking/turn-taking.
Key idea: implement a custom turn detector object with `on_partial`/`on_final` methods that the STT callback calls. When smart-turn signals end-of-turn, call the AgentSession turn APIs to immediately start/cancel TTS or claim the floor.
Example sketch (concise):
# example_turn_integration.py
from livekit.agents import AgentSession, inference, TurnHandlingOptions
from livekit.agents.turns import BaseTurnDetector # adapter base (pseudo-name - use actual SDK base if different)
from livekit.agents.session import AgentSessionTurnController # pseudo import for APIs to control turns
import smart_turn # pipecat-ai smart-turn python module
import asyncio
import time
class SmartTurnDetector(BaseTurnDetector):
def __init__(self, model_path=None, threshold=0.5):
# initialize smart-turn model per its API
self.model = smart_turn.load_model(model_path) # adapt to smart-turn loader
self.threshold = threshold
self._last_signal = 0
async def on_partial(self, partial_text, metadata=None):
# call smart-turn on partial transcript
score = self.model.predict_partial(partial_text, metadata=metadata) # adapt to actual API
if score >= self.threshold:
await self._signal_end_of_turn(score)
async def on_final(self, final_text, metadata=None):
score = self.model.predict_final(final_text, metadata=metadata) # adapt to actual API
if score >= self.threshold:
await self._signal_end_of_turn(score)
async def _signal_end_of_turn(self, score):
# immediate-on-signal behavior: call AgentSession turn control to let agent speak.
# Use debounce to avoid double-firing within short window
now = time.time()
if now - self._last_signal < 0.05: # tiny debounce (50ms)
return
self._last_signal = now
# The AgentSession exposes turn control; obtain controller from session context.
# This snippet assumes a global or injected reference to the active AgentSession or its controller:
if hasattr(self, "turn_controller"):
await self.turn_controller.request_agent_turn(immediate=True, reason="smart-turn")
else:
# fallback: set an event or callback the AgentSession listens to
if hasattr(self, "on_end_of_turn_callback"):
await self.on_end_of_turn_callback(score)
# --- wiring into AgentSession and STT callbacks ---
async def run_agent():
# create turn detector instance
detector = SmartTurnDetector(model_path="path/to/weights", threshold=0.5)
# build AgentSession with your STT/LLM/TTS
session = AgentSession(
stt=inference.STT(language="en", realtime=True),
llm=inference.LLM(...),
tts=inference.TTS(...),
turn_handling=TurnHandlingOptions(
# register a custom detector object (replace built-in)
turn_detection=detector,
# ensure session will honor external detector decisions
external_turn_detector=True, # pseudo-flag; adapt to SDK config
),
)
# provide detector access to session's turn controller if available
if hasattr(session, "turn_controller"):
detector.turn_controller = session.turn_controller
else:
# register a callback the session consumes to start agent speak
detector.on_end_of_turn_callback = session.trigger_agent_turn # adapt to actual API
# STT callback wiring: call detector on partials and finals
async def stt_callback(partial_text=None, final_text=None, metadata=None):
if partial_text:
await detector.on_partial(partial_text, metadata=metadata)
if final_text:
await detector.on_final(final_text, metadata=metadata)
# attach stt_callback to your STT stream (SDK-specific)
session.stt.on_transcript(stt_callback)
# start session (connect to LiveKit room etc.)
await session.start()
if __name__ == "__main__":
asyncio.run(run_agent())
Notes and practical tips
• Adapt function names: replace `predict_partial`/`predict_final`, loader, and any `turn_controller`/`trigger_agent_turn` calls to the exact smart-turn and livekit-agents APIs. The snippet shows integration points and minimal debounce (50ms).
• Immediate behavior: when smart-turn signals, call the agent turn API to cancel or preempt TTS and start agent response immediately.
• Latency: call smart-turn on each partial; keep the model loaded in memory to meet low-latency needs. The integration avoids subprocess calls to keep response fast.
• Avoid double-handling: unregister or disable LiveKit built-in detector (we used turn_handling.turn_detection=detector / external_turn_detector=True placeholder) — configure the AgentSession to accept your detector as the authoritative source.
• Confidence threshold: tune threshold to balance false positives/negatives. With immediate-on-signal you may prefer a slightly higher threshold if you see spurious triggers.
If you’d like, I can:
• Convert this sketch into a fully runnable code example using the exact livekit-agents v1.4 class/method names (I’ll need the precise SDK import names you see in your environment), or
• Provide a recommended threshold and debounce tuning steps based on observed false-positive rate.
Which would you prefer?
, with interactive elements