freezing-laptop-40127
12/23/2025, 3:37 PMtall-airline-16756
12/23/2025, 3:37 PMtall-airline-16756
12/23/2025, 3:38 PMfreezing-laptop-40127
12/23/2025, 3:40 PMtall-airline-16756
12/23/2025, 3:40 PMllm_node.
Which option you choose depends on whether you need streaming from Hugging Face. Hugging Face supports streaming via the inference/websocket or streaming responses from certain endpoints — if you can stream, the UX will be much smoother (lower latency). If not, you can still use non-streaming responses but will have slightly higher TTS/turn latency.
Option A — Use an OpenAI-compatible wrapper (if you have one)
• Wrap your Hugging Face model behind an OpenAI-compatible endpoint (or use a proxy that translates /chat/completions) so you can reuse LiveKit’s OpenAI plugin by pointing its base_url to your wrapper.
• Advantages: Minimal LiveKit code changes; leverages existing streaming handling if the wrapper supports it.
• Use this if you already have or can deploy a small proxy service.
Option B — Implement a custom llm_node that calls Hugging Face directly (recommended if you call Hugging Face API)
• Fully controlled approach: call the Hugging Face inference API (REST or streaming WebSocket), yield streamed chunks as LiveKit expects, and handle auth, retries, and tokenization specifics yourself.
• This is the approach below with sample code.
Sample: custom llm_node calling Hugging Face inference (async, streaming-friendly)
• Goals covered:
◦ Authenticate with Hugging Face API key
◦ Send conversation prompt as needed
◦ Stream tokens/chunks back into LiveKit by yielding llm.ChatChunk objects
◦ Handle non-streaming fallback
Example (Python-ish pseudocode for an Agent subclass):
import aiohttp
import asyncio
from livekit.agents import Agent, llm
HUGGINGFACE_API_KEY = "hf_XXXXXXXX"
class InsuranceAgent(Agent):
def __init__(self):
super().__init__(instructions="You are an insurance expert assistant.")
async def llm_node(self, chat_ctx, tools, model_settings=None):
# Build the prompt from chat_ctx.messages (adjust formatting to your model)
prompt = ""
for msg in chat_ctx.messages:
role = msg.role # e.g., "user" or "assistant"
content = msg.content
prompt += f"{role}: {content}\n"
prompt += "assistant:"
# Hugging Face inference endpoint for the model
url = "<https://api-inference.huggingface.co/models/bitext/Mistral-7B-Insurance>"
headers = {
"Authorization": f"Bearer {HUGGINGFACE_API_KEY}",
"Accept": "text/event-stream" # request streaming (if supported)
}
# Try streaming via SSE (event-stream). If HF doesn't stream, fall back.
try:
async with aiohttp.ClientSession() as session:
async with <http://session.post|session.post>(
url,
headers=headers,
json={"inputs": prompt, "parameters": {"max_new_tokens": 512, "temperature": 0.2}},
timeout=120
) as resp:
# If HF returns SSE/chunked streaming, process incrementally
if resp.status == 200 and resp.content_type == "text/event-stream":
async for raw_chunk in resp.content:
chunk_text = raw_chunk.decode(errors="ignore").strip()
if not chunk_text:
continue
# Parse SSE lines to extract token/text (HF SSE format may vary)
# Simple heuristic: yield each non-empty line as a ChatChunk
yield llm.ChatChunk(text=chunk_text)
else:
# Non-streaming response: read whole body
data = await resp.json()
# HF response format: either dict with 'generated_text' or list
text = ""
if isinstance(data, dict) and "generated_text" in data:
text = data["generated_text"]
elif isinstance(data, list) and len(data) > 0 and "generated_text" in data[0]:
text = data[0]["generated_text"]
else:
# fallback: stringify
text = str(data)
yield llm.ChatChunk(text=text)
except Exception as e:
# On error, yield an error message as a chunk or raise
yield llm.ChatChunk(text=f"[LLM error] {str(e)}")
Practical tips and considerations
• Streaming: If you can use Hugging Face's streaming (SSE/websocket) endpoint, parse the event stream and yield tokens quickly to avoid TTS latency. If not, return the full text and let TTS play after generation.
• Prompt formatting: Format prompts to the model’s expected chat or text-instruction format. Test locally to ensure quality in insurance domain.
• Safety & filtering: Add policy/safety checks after generation before sending to users (especially in insurance).
• STT / TTS: Configure LiveKit’s STT and TTS nodes (or external services) to transcribe user audio and synthesize the LLM output. Keep chunk sizes reasonable for TTS to avoid many tiny utterances.
• Retries & timeouts: Hugging Face inference can be slower for large models; implement retries, exponential backoff, and timeouts.
• Rate limits & batching: Respect Hugging Face rate limits; consider batching or a small queue if you expect many simultaneous users.
• Local wrap: If latency is critical, consider self-hosting the model and exposing a streaming-compatible endpoint (or use a local wrapper like vLLM) then call it as above.
Next step Would you like:
• A full runnable example that includes STT/TTS node wiring and LiveKit session setup?
• A version of llm_node that uses Hugging Face websocket streaming (I can produce a websocket example if you confirm you can use the HF WebSocket SSE endpoint)?
• Help formatting prompts for insurance — sample instruction + prompt templates?
Tell me which follow-up you want and I’ll provide the code and config.freezing-laptop-40127
12/27/2025, 7:59 AMnoise = noise_cancellation.BackgroundVoiceCancellation()
Cannot find reference 'BackgroundVoiceCancellation' in '__init__.py'
ai_session = AgentSession(
stt=stt,
llm=llm,
tts=tts,
vad=vad,
turn_detection="vad",
noise_cancellation=noise
)
Unexpected argument noise_cancellationtall-airline-16756
12/27/2025, 7:59 AMBackgroundVoiceCancellation isn't available, and AgentSession doesn't accept a noise_cancellation parameter. Here's the correct approach and a minimal example.
Short answer
• BackgroundVoiceCancellation is not a valid class. Use noise_cancellation.BVC() or noise_cancellation.BVCTelephony() instead.
• Configure noise cancellation via room_options (inside AudioInputOptions) when starting the session — do not pass noise_cancellation to AgentSession constructor.
Fix (minimal example)
from livekit.agents import AgentSession, room_io
from livekit.plugins import noise_cancellation, silero # or other VAD
session = AgentSession(
stt=stt,
llm=llm,
tts=tts,
vad=silero.VAD.load(),
turn_detection="vad",
)
await session.start(
room=ctx.room,
agent=agent,
room_options=room_io.RoomOptions(
audio_input=room_io.AudioInputOptions(
noise_cancellation=noise_cancellation.BVC(), # or BVCTelephony()
),
),
)
Notes and tips
• Use BVC() for general background cancellation, BVCTelephony() for telephony-optimized cancellation.
• Keep AgentSession args limited to stt/llm/tts/vad/turn_detection — audio noise settings go in room_options.
• If you still get import errors, ensure your installed LiveKit package version includes noise_cancellation plugin (upgrade to the latest release).
Would you like a websocket/SSE streaming example for your Hugging Face LLM or a runnable repo example that ties STT → llm_node → TTS with this noise setup?
Sources: Voice AI quickstart | LiveKit docs | Google AI and LiveKit | LiveKit Docs | Agent session | LiveKit docsfreezing-laptop-40127
12/27/2025, 8:12 AMtall-airline-16756
12/27/2025, 8:13 AM