Skip to content

Commit 12e417f

Browse files
authored
Merge pull request #3736: correct LiteLLM website transcription route
Validate the combined website and SenseVoice tree against current main. Signed-off-by: LauraGPT <18321252+LauraGPT@users.noreply.github.com>
2 parents 15c1959 + f950854 commit 12e417f

6 files changed

Lines changed: 156 additions & 118 deletions

File tree

‎docs/community_growth_20k.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ High-star feature requests and roadmap issues are earlier in the funnel than PRs
266266
| `deepset-ai/haystack-core-integrations#3572` FunASR-Haystack Python 3.14 installation | Removes an installation scare in Haystack's integration catalog that can prevent new users from trying FunASR | A current Windows CPython 3.14 resolver check succeeds with `funasr 1.3.14`, `umap-learn 0.5.12`, `pynndescent 0.6.0`, `numba 0.66.0`, and `llvmlite 0.48.0`; the reported `llvmlite 0.36.0` path is therefore more consistent with a stale lock or lagging package index than the current dependency graph. Diagnostic commands and requested lock/index evidence are at https://github.com/deepset-ai/haystack-core-integrations/issues/3572#issuecomment-4965365012. Do not change core packaging until the reporter provides a current failing resolution. |
267267
| `crewAIInc/crewAI#5983` FunASR for voice-enabled agents | Routes a 55k-star multi-agent framework toward a provider-neutral voice command path where FunASR/SenseVoice can be a local OpenAI-compatible transcription backend | LauraGPT revived the stale broad request with a concrete `voice.stt.*` config, multipart `/v1/audio/transcriptions` contract, mock endpoint test shape, and agent-command handoff at https://github.com/crewAIInc/crewAI/issues/5983#issuecomment-4901293351. Watch for maintainer direction before opening a code PR. |
268268
| `Significant-Gravitas/AutoGPT#13347` FunASR as an open-source STT backend | Keeps the 185k-star AutoGPT voice-input discussion anchored on a generic OpenAI-compatible transcription contract rather than a heavyweight FunASR-only dependency | LauraGPT mapped the existing hard-coded Copilot Whisper route, then opened PR `Significant-Gravitas/AutoGPT#13500` and linked it back at https://github.com/Significant-Gravitas/AutoGPT/issues/13347#issuecomment-4908286807. The PR later merged, so keep this as a completed high-visibility OpenAI-compatible STT contract win rather than an active operator item. |
269-
| `modelscope/FunASR#3334/#3350/#3361/#3362/#3363/#3366/#3398` owned conversion and link hygiene | Protects owned website, docs, runtime, model_zoo, and first-run troubleshooting surfaces that already send qualified traffic to the four repositories | Merged on 2026-07-23 and hardened again after the donor-page and troubleshooting reviews. `scripts/check_funasr_website_static.py` now patrols 14 public pages across home, ecosystem, donor, CLI tutorial, llama.cpp landing, llama.cpp blog, and launch-story surfaces. It requires the current `35K+` ecosystem proof, visible donor copy saying donations buy servers and the `www.funasr.com` domain, LiteLLM `custom_openai` routing, `funasr >= 1.3.26` CLI guidance, and `runtime-llamacpp-v0.1.9` download paths, including the Windows Vulkan ZIP, while forbidding stale `16K+`, `1.3.10`, and `runtime-llamacpp-v0.1.1` regressions. PRs #3361-#3363 refreshed high-traffic runtime download commands, package/help metadata, model_zoo Hugging Face links, and verified core ModelScope entries from stale `alibaba-damo-academy` / `damo` paths to current `modelscope/FunASR` / `iic` pages. `modelscope/FunASR#3366` then added README-linked install and deployment FAQs at [`docs/troubleshooting.md`](./troubleshooting.md) and [`docs/troubleshooting_zh.md`](./troubleshooting_zh.md), covering `torch` / `torchaudio`, ModelScope versus Hugging Face downloads, `funasr-server` `/v1/audio/transcriptions`, `WebSocket` realtime checks, `llama.cpp` / `GGUF`, and `Deployment Help` issue details. Post-merge validation passed the static contract suite, docs link guards, FAQ guards, real public website contract runs across all 14 pages, and HTTP 200 checks for updated owned/model links. |
269+
| `modelscope/FunASR#3334/#3350/#3361/#3362/#3363/#3366/#3398` owned conversion and link hygiene | Protects owned website, docs, runtime, model_zoo, and first-run troubleshooting surfaces that already send qualified traffic to the four repositories | Historical July 2026 record: these PRs protected 14 public pages, donor usage copy, CLI installation guidance, runtime downloads, model links, and the README-linked [English](./troubleshooting.md) / [Chinese](./troubleshooting_zh.md) troubleshooting guides. Their original static, link, FAQ, and public HTTP checks passed, but the old LiteLLM `custom_openai` assertion was incorrect for transcription. The September 29 correction requires visible `openai/sensevoice` and an explicit self-hosted `api_base`, rejects the old route and checkpoint-ID example, and updates both ecosystem source pages. Source validation is separate from publication; it does not establish that the live website has deployed the correction. |
270270
| `modelscope/FunClip#188/#189`, `QwenAudio/Fun-ASR#151`, `QwenAudio/SenseVoice#327` four-repo community templates | Reduces maintainer follow-up and makes first external contributions easier to review across the four core repositories | Merged on 2026-07-23 after the four-repo template inventory. The four core repositories now have `CONTRIBUTING.md`, issue templates, and PR templates. FunClip gained bug/feature issue templates, a PR template, CONTRIBUTING.md, and template guards; Fun-ASR gained a PR template covering Nano, MLT, streaming, vLLM, GGUF, and HF/ModelScope routing; SenseVoice gained a PR template covering ASR, emotion/event tags, API/web UI/ONNX/Docker, GGUF, and model-card routing. Post-merge validation passed the new template guards plus each repo's lightweight docs/runtime smoke tests. |
271271
| `chatchat-space/Langchain-Chatchat#5479` FunASR/SenseVoice voice input | Puts FunASR in a 38k-star Chinese RAG/Agent app where local audio upload can feed existing Chat and knowledge-base flows | LauraGPT proposed an OpenAI-compatible ASR endpoint slice, including `asr.base_url`, multipart request shape, minimal `{ "text": "..." }` response, and mocked CI endpoint at https://github.com/chatchat-space/Langchain-Chatchat/issues/5479#issuecomment-4901293565. Monitor stale handling and maintainer appetite for a first audio-upload transcription path. |
272272
| `royshil/obs-localvocal#314` SenseVoice/Paraformer engine option | Opens an OBS live-captioning path where SenseVoice/Paraformer can be evaluated through a cleaner ASR-engine boundary instead of a Whisper-only runtime | Maintainer is interested but capacity-limited until mid/late August. LauraGPT mapped current Whisper coupling points and suggested a facade-only first refactor at https://github.com/royshil/obs-localvocal/issues/314#issuecomment-4909662013; wait for a refactor branch or review request before proposing Sherpa-ONNX/FunASR runtime code. |
@@ -302,7 +302,7 @@ High-star feature requests and roadmap issues are earlier in the funnel than PRs
302302
| `zts212653/clowder-ai#1083` Qwen3-ASR service unification | Puts Qwen3-ASR into a user-facing local STT service slot by making it a `whisper-stt` backend variant instead of a separate, easier-to-misconfigure service | Merged on 2026-07-13 as `704bb735cae01be4bcd4089427bc6983c99a43a3` after fixes for Rosetta hardware detection, Qwen3-ASR install/server dispatch, async backend locking, temp WAV cleanup, and stale setup docs. The upstream service slot is already discoverable from the FunASR EN/ZH community integrations pages. |
303303
| `run-llama/llama_index#21958` FunASR endpoint reader | Puts FunASR behind a LlamaIndex reader for OpenAI-compatible transcription endpoints used in RAG and agent pipelines | LauraGPT rechecked head `07a8599deaebe5e7a559d62174e7a872870c2f7e` at https://github.com/run-llama/llama_index/pull/21958#issuecomment-4905345545; author acknowledged the shared-reader pytest caveat at https://github.com/run-llama/llama_index/pull/21958#issuecomment-4905384536. Keep the endpoint contract clear and avoid forcing local `funasr` dependencies into the main package. |
304304
| `run-llama/llama_index#21996` local FunASR reader | Gives LlamaIndex users a local SenseVoice/FunASR reader for private transcription workflows | Keep optional dependencies isolated, verify the reader does not affect default installs, and watch for maintainer guidance on package extras. |
305-
| `BerriAI/litellm-docs#610` FunASR transcription proxy docs | Puts FunASR/SenseVoice behind LiteLLM's existing OpenAI-compatible `custom_openai` audio transcription route, reaching teams that already deploy LiteLLM gateways | Rebased across the upstream `docs/audio_transcription.md` conflict on 2026-07-23; head `1a70fa02` is mergeable with CodeRabbit, Vercel, and Vercel preview comments all green. The docs now keep upstream's `mock_testing_fallbacks` deprecation note for Proxy requests, use `funasr>=1.3.26`, preserve `api_base: http://localhost:8000/v1`, and avoid installing `vllm` in the basic setup path. Local validation passed `git diff --check`, content assertions, and `npm run build`; build warnings are existing site-wide Docusaurus broken links outside `/docs/audio_transcription`. Evidence posted at https://github.com/BerriAI/litellm-docs/pull/610#issuecomment-5049681978. |
305+
| `BerriAI/litellm-docs#610` FunASR transcription proxy docs | Routes self-hosted FunASR/SenseVoice transcription through LiteLLM's `openai/sensevoice` provider/model with an explicit backend `api_base`, reaching teams that deploy LiteLLM gateways | At 2026-09-29 02:26 UTC, signed head `64ab922e497ce0f181565e31c9b29025f48b01e6` includes 883 upstream main commits and corrects the unsupported `custom_openai` transcription provider, checkpoint-ID model name, and weak Proxy master-key example. Native LiteLLM 1.103.0 / OpenAI SDK transport checks, FunASR 1.4.16 ASGI tests with inference stubbed, and the exact-main master-key guard passed 14 focused tests; the documentation build produced 1,357 HTML pages and desktop/mobile browser checks passed. No speech model was downloaded or inferred, and a live Proxy was not booted. The PR remains open: hosted docs checks require approval with zero jobs run, and Vercel deployment is pending. The green July checks and successful preview-comment integration are not evidence of a current successful deployment. [Current PR and validation](https://github.com/BerriAI/litellm-docs/pull/610). |
306306
| `mem0ai/mem0#5571` optional FunASR transcription helper | Adds local FunASR transcription to a high-star memory layer used by agent builders | Keep FunASR optional and make examples clear about local model downloads; the current failing Vercel preview is a Mem0 team authorization gate, not a FunASR code failure, so wait for maintainer-side preview access or review. |
307307
| `Significant-Gravitas/AutoGPT#13500` configurable transcription endpoints | Opens a path from AutoGPT's high-visibility agent platform to local FunASR/SenseVoice gateways through the existing OpenAI-compatible transcription route | Merged on 2026-07-22 after the review and status gates cleared. The merged path keeps transcription provider configuration generic, so FunASR/SenseVoice can fit through an OpenAI-compatible endpoint without adding a heavyweight toolkit dependency to AutoGPT. |
308308
| `Vexa-ai/vexa#810` custom STT endpoint documentation | Makes bring-your-own OpenAI-compatible transcription servers visible in a meeting-bot docs surface, giving SenseVoiceSmall and Fun-ASR-Nano users a clean path to point Vexa at private FunASR/SenseVoice gateways | Delivered via Vexa's community-batch release `#867`, merged to `main` as `e617d839` and shipped in `v0.12.16` with `docs/docs/how-to/custom-stt.mdx`. Maintainer confirmed on 2026-07-22 that #810 is superseded by the delivered release content, so treat the closed #810 PR as completed evidence rather than an active merge-card gate. |

‎scripts/check_funasr_website_static.py‎

Lines changed: 30 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,7 @@
1616

1717

1818
BASE_URL = "https://www.funasr.com"
19-
DONOR_PAGE_URLS = frozenset(
20-
(f"{BASE_URL}/donors.html", f"{BASE_URL}/en/donors.html")
21-
)
19+
DONOR_PAGE_URLS = frozenset((f"{BASE_URL}/donors.html", f"{BASE_URL}/en/donors.html"))
2220

2321

2422
@dataclass(frozen=True)
@@ -57,13 +55,18 @@ class StaticAssetContract:
5755
),
5856
f"{BASE_URL}/ecosystem.html": PageContract(
5957
required=(
60-
"36K+",
58+
"37K+",
6159
"/donors.html",
6260
"LiteLLM",
63-
"custom_openai",
6461
"54.3K stars",
6562
),
63+
visible_required=("api_base",),
6664
visible_patterns=(
65+
("openai/sensevoice", r"(?<![\w/])openai/sensevoice(?![\w./+-])"),
66+
(
67+
"http://127.0.0.1:8000/v1",
68+
r"(?<![\w/])http://127\.0\.0\.1:8000/v1(?![\w/?#.:+-])",
69+
),
6770
("FunASR 官方插件 0.1.1", r"FunASR 官方插件 0\.1\.1(?![\w.+-])"),
6871
("最大 25 MB 音频上传", r"最大 (?<!\d)25 MB 音频上传"),
6972
),
@@ -75,17 +78,22 @@ class StaticAssetContract:
7578
"https://github.com/0xShug0/audio.cpp/blob/1778b23a5f6a4951c788e4bb0e7baa04f20012a2/docs/models/fun_asr_nano.md",
7679
"https://github.com/RVC-Boss/GPT-SoVITS/pull/2824",
7780
),
78-
forbidden=("16K+",),
81+
forbidden=("16K+", "custom_openai", "openai/FunAudioLLM/SenseVoiceSmall"),
7982
),
8083
f"{BASE_URL}/en/ecosystem.html": PageContract(
8184
required=(
82-
"36K+",
85+
"37K+",
8386
"/en/donors.html",
8487
"LiteLLM",
85-
"custom_openai",
8688
"54.3K stars",
8789
),
90+
visible_required=("api_base",),
8891
visible_patterns=(
92+
("openai/sensevoice", r"(?<![\w/])openai/sensevoice(?![\w./+-])"),
93+
(
94+
"http://127.0.0.1:8000/v1",
95+
r"(?<![\w/])http://127\.0\.0\.1:8000/v1(?![\w/?#.:+-])",
96+
),
8997
("FunASR plugin 0.1.1", r"FunASR plugin 0\.1\.1(?![\w.+-])"),
9098
("25 MB uploads", r"(?<!\d)25 MB uploads"),
9199
),
@@ -97,7 +105,7 @@ class StaticAssetContract:
97105
"https://github.com/0xShug0/audio.cpp/blob/1778b23a5f6a4951c788e4bb0e7baa04f20012a2/docs/models/fun_asr_nano.md",
98106
"https://github.com/RVC-Boss/GPT-SoVITS/pull/2824",
99107
),
100-
forbidden=("16K+",),
108+
forbidden=("16K+", "custom_openai", "openai/FunAudioLLM/SenseVoiceSmall"),
101109
),
102110
f"{BASE_URL}/donors.html": PageContract(
103111
required=(
@@ -444,9 +452,7 @@ def handle_starttag(self, tag: str, attrs: list[tuple[str, str | None]]) -> None
444452
tag = tag.lower()
445453
attributes = {name.lower(): value for name, value in attrs}
446454
hidden = (
447-
self._parent_hidden
448-
or tag in _HIDDEN_TAGS
449-
or self._has_hidden_attribute(attributes)
455+
self._parent_hidden or tag in _HIDDEN_TAGS or self._has_hidden_attribute(attributes)
450456
)
451457
if not hidden:
452458
if tag == "img" and attributes.get("src"):
@@ -460,9 +466,7 @@ def handle_startendtag(self, tag: str, attrs: list[tuple[str, str | None]]) -> N
460466
tag = tag.lower()
461467
attributes = {name.lower(): value for name, value in attrs}
462468
hidden = (
463-
self._parent_hidden
464-
or tag in _HIDDEN_TAGS
465-
or self._has_hidden_attribute(attributes)
469+
self._parent_hidden or tag in _HIDDEN_TAGS or self._has_hidden_attribute(attributes)
466470
)
467471
if not hidden and tag == "img" and attributes.get("src"):
468472
self.images.add(attributes["src"])
@@ -541,10 +545,7 @@ def handle_starttag(self, tag: str, attrs: list[tuple[str, str | None]]) -> None
541545
tag = tag.lower()
542546
attributes = {name.lower(): value for name, value in attrs}
543547
if not self._stack:
544-
is_navigation = (
545-
tag == "div"
546-
and "nav-links" in (attributes.get("class") or "").split()
547-
)
548+
is_navigation = tag == "div" and "nav-links" in (attributes.get("class") or "").split()
548549
if not is_navigation:
549550
return
550551
self.found_navigation = True
@@ -619,9 +620,7 @@ def validate_navigation(pages: dict[str, str]) -> list[str]:
619620
directory_links: list[DirectoryLink] = []
620621
for link in navigation_links:
621622
target = urlparse(urljoin(url, link.href))
622-
is_language_toggle = (
623-
target.netloc == "www.funasr.com" and target.path == alternate_path
624-
)
623+
is_language_toggle = target.netloc == "www.funasr.com" and target.path == alternate_path
625624
is_github_action = target.netloc == "github.com"
626625
if not is_language_toggle and not is_github_action:
627626
directory_links.append(link)
@@ -633,21 +632,14 @@ def validate_navigation(pages: dict[str, str]) -> list[str]:
633632
expected_links = [link for link in navigation_links if link.href == expected]
634633
if not any(link.label in expected_labels for link in expected_links):
635634
label_description = "` or `".join(expected_labels)
636-
failures.append(
637-
f"{url}: `{expected}` must use visible label `{label_description}`"
638-
)
639-
if expected in links and (
640-
not directory_links or directory_links[-1].href != expected
641-
):
635+
failures.append(f"{url}: `{expected}` must use visible label `{label_description}`")
636+
if expected in links and (not directory_links or directory_links[-1].href != expected):
642637
failures.append(f"{url}: `{expected}` must be the last directory link")
643638
if links.count(expected) > 1:
644-
failures.append(
645-
f"{url}: directory navigation contains duplicate `{expected}`"
646-
)
639+
failures.append(f"{url}: directory navigation contains duplicate `{expected}`")
647640
if wrong_language in links:
648641
failures.append(
649-
f"{url}: directory navigation contains wrong-language "
650-
f"`{wrong_language}`"
642+
f"{url}: directory navigation contains wrong-language " f"`{wrong_language}`"
651643
)
652644
return failures
653645

@@ -723,9 +715,7 @@ def validate_assets(assets: dict[str, bytes]) -> list[str]:
723715
return failures
724716

725717

726-
def _fetch_bytes(
727-
url: str, timeout: float, retries: int, require_exact_url: bool = False
728-
) -> bytes:
718+
def _fetch_bytes(url: str, timeout: float, retries: int, require_exact_url: bool = False) -> bytes:
729719
last_error: Exception | None = None
730720
for attempt in range(retries + 1):
731721
try:
@@ -741,17 +731,13 @@ def _fetch_bytes(
741731
raise last_error
742732

743733

744-
def _fetch_url(
745-
url: str, timeout: float, retries: int, require_exact_url: bool = False
746-
) -> str:
734+
def _fetch_url(url: str, timeout: float, retries: int, require_exact_url: bool = False) -> str:
747735
return _fetch_bytes(
748736
url,
749737
timeout=timeout,
750738
retries=retries,
751739
require_exact_url=require_exact_url,
752-
).decode(
753-
"utf-8", errors="replace"
754-
)
740+
).decode("utf-8", errors="replace")
755741

756742

757743
def fetch_pages(timeout: float, retries: int = 3) -> dict[str, str]:
@@ -790,9 +776,7 @@ def main(argv: list[str] | None = None) -> int:
790776
parser.add_argument("--retries", type=int, default=3)
791777
args = parser.parse_args(argv)
792778

793-
navigation_pages = fetch_navigation_pages(
794-
timeout=args.timeout, retries=args.retries
795-
)
779+
navigation_pages = fetch_navigation_pages(timeout=args.timeout, retries=args.retries)
796780
pages = {}
797781
for url in PAGE_CONTRACTS:
798782
if url in DONOR_PAGE_URLS:
@@ -810,9 +794,7 @@ def main(argv: list[str] | None = None) -> int:
810794
all_navigation_pages.update(pages)
811795
failures = validate_pages(pages)
812796
failures.extend(validate_navigation(all_navigation_pages))
813-
failures.extend(
814-
validate_assets(fetch_assets(timeout=args.timeout, retries=args.retries))
815-
)
797+
failures.extend(validate_assets(fetch_assets(timeout=args.timeout, retries=args.retries)))
816798
if failures:
817799
print("funasr.com static page contract failed:", file=sys.stderr)
818800
for failure in failures:

0 commit comments

Comments
 (0)