Skip to content

feat(nabrah): add Nabrah STT plugin for LiveKit Agents with installation and usage instructions - #6873

Open
MagdiWaleed wants to merge 3 commits into
livekit:mainfrom
MagdiWaleed:magdi/add-nabrah-plugin
Open

feat(nabrah): add Nabrah STT plugin for LiveKit Agents with installation and usage instructions#6873
MagdiWaleed wants to merge 3 commits into
livekit:mainfrom
MagdiWaleed:magdi/add-nabrah-plugin

Conversation

@MagdiWaleed

Copy link
Copy Markdown

No description provided.

@MagdiWaleed
MagdiWaleed requested a review from a team as a code owner August 16, 2026 14:25
@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

devin-ai-integration[bot]

This comment was marked as resolved.

- add py.typed marker so mypy can check the package
- give _recognize_impl the base-class signature
- narrow self._stt and use LanguageCode for SpeechData
- guard NotGivenOr word timestamps before segment bounds
- register the plugin in the uv workspace sources and the
  livekit-agents extras, align version with the repo baseline
- flesh out package metadata, run ruff format
@MagdiWaleed
MagdiWaleed force-pushed the magdi/add-nabrah-plugin branch from 0964d9a to d0f1f3c Compare August 16, 2026 15:13

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Devin Review found 1 new potential issue.

View 5 additional findings in Devin Review.

Open in Devin Review

Comment on lines +422 to +424
self._utt_flushed_clean = _normalize_whitespace(
self._utt_flushed_clean + " " + self._utt_clean,
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Already-finalized speech can be repeated in a later transcript within the same turn

Text already sent as final is recorded with an extra space inserted before punctuation (_utt_flushed_clean + " " + self._utt_clean at livekit-plugins/livekit-plugins-nabrah/livekit/plugins/nabrah/stt.py:422-424), so the bookkeeping no longer matches what the recognizer sends and the same speech is emitted again.
Impact: A user's earlier sentence can be duplicated in the next transcript of the same turn, which is then fed to the LLM.

Prefix-matching mismatch between `_flush_eos` accumulation and the recognizer's cumulative text

_process_message computes the not-yet-finalized part of the current utterance by stripping the already-flushed prefix: clean_now[len(self._utt_flushed_clean):] if self._utt_flushed_clean and clean_now.startswith(self._utt_flushed_clean) (livekit-plugins/livekit-plugins-nabrah/livekit/plugins/nabrah/stt.py:523-527). That prefix is rebuilt in _flush_eos by joining pieces with a literal space and normalizing whitespace, unlike _current_text which deliberately omits the space when the next piece starts with punctuation (livekit-plugins/livekit-plugins-nabrah/livekit/plugins/nabrah/stt.py:367-370).

Concrete sequence inside one recognizer utterance (no is_final in between, which the module docstring says is routine):

  1. message: "مرحبا <eot>"_utt_clean = "مرحبا"; EOT confirm fires → flush; _utt_flushed_clean = "مرحبا".
  2. message: "مرحبا. كيف"clean_now.startswith("مرحبا")_utt_clean = ". كيف".
  3. second EOT → flush → _utt_flushed_clean = normalize("مرحبا" + " " + ". كيف") = "مرحبا . كيف".
  4. next message "مرحبا. كيف حالك" does not start with "مرحبا . كيف", so _utt_clean falls back to the whole clean_now, and the following FINAL_TRANSCRIPT repeats text already emitted as final.

The same unconditional " " join is used when rolling an utterance into the turn (livekit-plugins/livekit-plugins-nabrah/livekit/plugins/nabrah/stt.py:500-502), which additionally inserts a stray space before punctuation in emitted transcripts.

Prompt for agents
In livekit-plugins/livekit-plugins-nabrah/livekit/plugins/nabrah/stt.py, `_flush_eos` rebuilds the already-emitted prefix of the current utterance as `_normalize_whitespace(self._utt_flushed_clean + " " + self._utt_clean)`, and `_process_message` later strips that prefix from the recognizer's cumulative normalized text via `clean_now.startswith(self._utt_flushed_clean)`. Because the recognizer's own text has no space before punctuation ("مرحبا. كيف") while the reconstruction always inserts one ("مرحبا . كيف"), the prefix check can fail after a mid-utterance flush whose following diff starts with punctuation; `_utt_clean` then falls back to the entire utterance and already-finalized text is emitted again in the next FINAL_TRANSCRIPT. Consider tracking the flushed prefix by character offset into the normalized cumulative utterance text (e.g. store `len(clean_now)` consumed at flush time) instead of re-concatenating strings, or reuse the same punctuation-aware separator logic used in `_current_text` for both this join and the `_turn_text` join in the `not continues` branch.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

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.

2 participants