feat: add funasr STT plugin (local FunASR / SenseVoice)#606
Conversation
fb7be78 to
21b8744
Compare
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughAdds a new Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (3)
plugins/funasr/tests/test_funasr_stt.py (1)
5-25: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick winOrganize tests in a test class.
Per path instructions, unit tests for a class should be kept in a test class. Wrap
test_stt_construct()andtest_stt_custom_params()in aTestSTTclass.Proposed refactor
def test_stt_construct(): - """The plugin constructs and exposes the expected defaults without loading a model.""" +class TestSTT: + def test_construct(self): + """The plugin constructs and exposes the expected defaults without loading a model.""" - stt = funasr.STT() - assert stt.provider_name == "funasr" - assert stt.model_id == "iic/SenseVoiceSmall" - assert stt.language == "auto" - assert stt.device == "cpu" - assert stt.use_itn is True - - -def test_stt_custom_params(): - stt = funasr.STT( - model="FunAudioLLM/Fun-ASR-Nano-2512", - language="zh", - device="cuda", - use_itn=False, - ) - assert stt.model_id == "FunAudioLLM/Fun-ASR-Nano-2512" - assert stt.language == "zh" - assert stt.device == "cuda" - assert stt.use_itn is False + stt = funasr.STT() + assert stt.provider_name == "funasr" + assert stt.model_id == "iic/SenseVoiceSmall" + assert stt.language == "auto" + assert stt.device == "cpu" + assert stt.use_itn is True + + def test_custom_params(self): + stt = funasr.STT( + model="FunAudioLLM/Fun-ASR-Nano-2512", + language="zh", + device="cuda", + use_itn=False, + ) + assert stt.model_id == "FunAudioLLM/Fun-ASR-Nano-2512" + assert stt.language == "zh" + assert stt.device == "cuda" + assert stt.use_itn is FalseSource: Path instructions
plugins/funasr/example/funasr_example.py (1)
9-10: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick winAdd return type annotation to
build_stt().Per coding guidelines, use type annotations everywhere. The function should declare its return type.
Proposed fix
-def build_stt(): - return funasr.STT(model="iic/SenseVoiceSmall", language="auto", device="cpu") +def build_stt() -> funasr.STT: + return funasr.STT(model="iic/SenseVoiceSmall", language="auto", device="cpu")Source: Coding guidelines
plugins/funasr/vision_agents/plugins/funasr/stt.py (1)
41-48: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd explicit return type annotations on public/private methods.
__init__,process_audio, and_process_buffershould declare-> Nonefor consistent typing in this codebase.Proposed fix
- def __init__( + def __init__( self, model: str = "iic/SenseVoiceSmall", language: str = "auto", device: str = "cpu", use_itn: bool = True, client: Optional[AutoModel] = None, - ): + ) -> None:- async def process_audio( + async def process_audio( self, pcm_data: PcmData, participant: Participant, - ): + ) -> None:- async def _process_buffer(self, participant: Participant): + async def _process_buffer(self, participant: Participant) -> None:As per coding guidelines, "Use type annotations everywhere."
Also applies to: 96-100, 142-143
Source: Coding guidelines
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 59d3e3e7-aa2a-4f96-8367-acb8e3eae5b7
📒 Files selected for processing (8)
plugins/funasr/README.mdplugins/funasr/example/__init__.pyplugins/funasr/example/funasr_example.pyplugins/funasr/py.typedplugins/funasr/pyproject.tomlplugins/funasr/tests/test_funasr_stt.pyplugins/funasr/vision_agents/plugins/funasr/__init__.pyplugins/funasr/vision_agents/plugins/funasr/stt.py
21b8744 to
e05f50b
Compare
|
Thanks for the review! Addressed two of the three:
On the other two, I intentionally mirrored the existing |
|
Updated the branch to address the remaining review threads:
Local verification:
|
There was a problem hiding this comment.
🧹 Nitpick comments (1)
plugins/funasr/tests/test_funasr_stt.py (1)
81-94: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAvoid patching private methods in this test.
Lines 91-94 replace
stt._transcribeand callstt._process_buffer()directly, which makes the assertion path-dependent and violates this repo’s test guidance. Use a fakeclient.generate()that raisesAssertionErrorand drive the failure throughprocess_audio()instead, so the regression stays covered through public behavior.Sources: Coding guidelines, Path instructions
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 7e11fa38-82b7-4d3b-ac91-678198d8afd3
📒 Files selected for processing (3)
plugins/funasr/pyproject.tomlplugins/funasr/tests/test_funasr_stt.pyplugins/funasr/vision_agents/plugins/funasr/stt.py
🚧 Files skipped from review as they are similar to previous changes (2)
- plugins/funasr/pyproject.toml
- plugins/funasr/vision_agents/plugins/funasr/stt.py
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 291ce366-675b-4a1d-a8b6-ebe943a2fb36
📒 Files selected for processing (1)
plugins/funasr/tests/test_funasr_stt.py
|
Fresh FunASR/SenseVoice-side validation recheck (2026-07-07 UTC):
From the FunASR plugin side this looks ready for human maintainer review. |
4cc511b to
8f71dc8
Compare
|
Synced this PR with current Thread-aware review audit still shows all 4 prior CodeRabbit threads resolved/outdated. The only visible completed GitHub check on the new head, Fresh validation on the synced head with the repository lock environment:
The PR remains non-draft and blocked only by maintainer review. |
Adds a
funasrSTT plugin: a local, self-hosted speech-to-text backend powered by FunASR (SenseVoice / Fun-ASR-Nano / Paraformer). It is strong on Chinese, Cantonese, Japanese, Korean, and more; it runs on CPU or CUDA and requires no API key.What it does
STT(stt.STT, Warmable[Optional[AutoModel]])with buffered offline transcription through the public Vision Agents audio path.AutoModelduring warmup; model inference runs off the event loop and emits finalTranscriptResponseitems with SenseVoice tags removed.iic/SenseVoiceSmall; callers can selectFunAudioLLM/Fun-ASR-Nano-2512, Paraformer, or another FunASR-compatible model.Repository integration
plugins/funasras a uv workspace member and source.vision-agents[funasr]extra and locks the complete dependency graph.Validation
Verified on exact head
8f71dc851d2c80f2c0a91608f33a9557a5904939, rebased onto019edac7726987b1c5c18580e06b59d59387409c:uv sync --all-extras --dev --frozen: 452 packages resolved; every workspace package, includingvision-agents-plugins-funasr, built successfully.getstream.PcmDataimplementation.ruff check .andruff format --check .: passed across 536 files.dev.py validate-extras: passed.funasr>=1.1.0andvision-agentsand contains only the FunASR package files.STT.warmup()->process_audio()-> public output stream succeeded withiic/SenseVoiceSmall; the sample produced开饭时间早上9点至下午5点。, languagezh, with SenseVoice tags removed.blockbusterrejecting Anthropic's credential-fileos.stat; no FunASR test failed.