krisp VIVA: native filter is built on the event loop on the first audio frame (200-800 ms block)
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 45/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Active
- Tech stack
- python
- Domain
- audio-video-rtc
Research direction
Start with livekit/plugins/krisp_internal and livekit/rtc/audio_stream.py, then trace KrispVivaFilterFrameProcessor._process and the credential and stream info update paths. Confirm where native filter construction runs relative to the asyncio event loop, and compare its behavior before credentials arrive. Done means construction no longer blocks the loop and frames pass through unfiltered until the filter is ready.
Written by the indexing model from the issue text.
Description
Versions: livekit-agents 1.8.8, livekit-plugins-krisp 0.4.8, livekit-plugins-krisp-internal 0.2.0, Python 3.13, Linux (t3.small).
What happens
krisp.voice_isolation() (Cloud auth) returns a processor whose backend, krisp_internal.plugin.KrispVivaFilterFrameProcessor, constructs the native KrispVivaFilter inside _process on the first frame after _on_credentials_updated. Its docstring says this keeps the blocking init "on the audio thread, not on the room task". But _process is called from rtc.AudioStream's async iterator (livekit/rtc/audio_stream.py, frame = self._processor._process(frame)), so construction runs on the job's asyncio event loop.
The agents loop monitor reports it in nearly every session, right before the first reply:
event loop blocked for 830ms at ".../livekit/plugins/krisp_internal/_ffi.py", line 293, in _uniffi_rust_call_with_error
Across ~20 sessions it ranged from 205 to 830 ms, sometimes as two blocks in one session. Timing the native call directly: KrispVivaFilter(KrispVivaFilterSettings(...)) takes 114-250 ms on an M-series Mac and longer on a small cloud VM. With credentials and stream info set, the first process() afterwards takes ~0.1 ms, so construction is essentially the whole cost.
Expected
Filter construction off the event loop, with frames passed through unfiltered until it is ready. That is the processor's existing behaviour before credentials arrive.
Workaround we ship
We subclass the processor: when a frame needs a filter, _process starts one worker thread that constructs the native filter, returns the frame unfiltered, and adopts the finished filter on the next frame (on the loop thread, applying any stream info, credentials or level that changed during the build). After that, frames go through the unchanged _process. With this, the loop-monitor warning is gone, and the build (327-502 ms on staging) happens on the worker thread. Happy to share the code if useful.
Possible upstream fixes: construct the filter in a thread from _on_credentials_updated / _on_stream_info_updated, or have AudioStream call blocking processors via an executor.
- Dominant language
- Python
- Stars
- 14.6k
- Forks
- 3.9k
- Avg merge
- 3d 18h
- Merged PRs (30d)
- 193
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from livekit/agents
-
Google TTS: default ssml_gender NEUTRAL is rejected for Neural2 voicesPossibly taken @sarankumar1325 claimed this 1 day ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Maintainers usually reply within 1 day
-
Assistant markup is stripped from chat history when expressive mode is offPossibly taken @ShivamSharma43 claimed this 13 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Maintainers usually reply within 1 day
-
docs: openai.LLM vs openai.responses.LLM for HTTP OpenAI-compat hostsMay be free again @AbarnaaSree claimed this 52 days ago, and no pull request is open. Open
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
livekit/agents#7022 · 1 comment ·
Maintainers usually reply within 1 day
-
google realtime (Gemini Live): manual activity detection — barge-in fires on the model's own generation; unclosed transcript-only generation blocks later generate_replyPossibly taken @akashhguptaa claimed this today. Open
Difficulty 4/5 3-5 days Newbie friendliness 30/100
Maintainers usually reply within 1 day
-
Difficulty 5/5 Over a week Newbie friendliness 35/100
Maintainers usually reply within 1 day
Similar issues
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
anchore/grype-db#1149 · 1 comment ·
Maintainers usually reply within 1 day
-
[Bug]: `hermes plugins update` clones an entire monorepo twice - `subdir` is resolved but dropped at both catalog-update call sitesPossibly taken @HootRock claimed this today. Opencomp/cli P2 type/perf
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
NousResearch/hermes-agent#142417 · 2 comments ·
Maintainers usually reply within 1 day
-
SMC SPEC
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
tenstorrent/tt-oca-harness#3287 ·
Maintainers usually reply within 1 day
-
bug enhancement python
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
DewaldOosthuizen/tech-cheat-sheets-and-notes#392 ·
Maintainers usually reply within 1 day
-
security
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
fabriziosalmi/wildbox#801 ·
Maintainers usually reply within 1 day