@@ -67,6 +67,7 @@ def _whisper_cpp(
6767 description : str = "OpenAI Whisper converted for the standalone whisper.cpp engine." ,
6868 source : str = "whisper.cpp" ,
6969 language_codes : tuple [str , ...] = (),
70+ license_name : str = "See model source" ,
7071) -> CatalogModel :
7172 return CatalogModel (
7273 id = f"{ ENGINE_WHISPER_CPP } :{ key } " ,
@@ -83,6 +84,7 @@ def _whisper_cpp(
8384 description = description ,
8485 source = source ,
8586 language_codes = language_codes or _whisper_language_codes (languages ),
87+ license_name = license_name ,
8688 )
8789
8890
@@ -138,7 +140,8 @@ def _faster_whisper(
138140 huggingface_folder = "" ,
139141 family = "Whisper / CTranslate2" ,
140142 description = (
141- "Persistent CTranslate2 model with CPU INT8 inference; optimized for Linux servers."
143+ "Persistent CTranslate2 model with CPU INT8 inference; "
144+ "works well on desktop and server CPUs."
142145 ),
143146 source = "faster-whisper" ,
144147 marker_file = "model.bin" ,
@@ -419,6 +422,72 @@ def _whisper_language_codes(languages: str) -> tuple[str, ...]:
419422}
420423
421424
425+ def catalog_source_url (model : CatalogModel ) -> str | None :
426+ """Best public page for a catalog entry (Hugging Face repo or project site).
427+
428+ Prefers a browsable page over a raw .tar/.bin download blob.
429+ """
430+ if model .huggingface_repo :
431+ return f"https://huggingface.co/{ model .huggingface_repo } "
432+ if model .download_url and "huggingface.co/" in model .download_url :
433+ url = model .download_url
434+ if "/resolve/" in url :
435+ head , _ , _ = url .partition ("/resolve/" )
436+ return head
437+ return url
438+ # Release/tag pages are more specific than a project root (e.g. SenseVoice /
439+ # Parakeet v3 ship only as sherpa-onnx GitHub release assets).
440+ release = _github_release_page (model .archive_url )
441+ if release :
442+ return release
443+ # Label-specific pages (Handy, Breeze, …) before generic engine fallbacks —
444+ # otherwise Handy builds incorrectly link to whisper.cpp's GitHub.
445+ labeled = _SOURCE_LABEL_URLS .get (model .source )
446+ if labeled :
447+ return labeled
448+ project = _ENGINE_SOURCE_URLS .get (model .engine )
449+ if project :
450+ return project
451+ if model .download_url :
452+ return model .download_url
453+ if model .archive_url :
454+ return model .archive_url
455+ return None
456+
457+
458+ def _github_release_page (archive_url : str | None ) -> str | None :
459+ """Turn a GitHub release asset URL into the browsable release/tag page."""
460+ if not archive_url or "/releases/download/" not in archive_url :
461+ return None
462+ head , _ , rest = archive_url .partition ("/releases/download/" )
463+ if not head .startswith ("https://github.com/" ) or not rest :
464+ return None
465+ tag = rest .split ("/" , maxsplit = 1 )[0 ]
466+ return f"{ head } /releases/tag/{ tag } " if tag else None
467+
468+
469+ _ENGINE_SOURCE_URLS = {
470+ ENGINE_WHISPER_CPP : "https://github.com/ggml-org/whisper.cpp" ,
471+ ENGINE_WHISPERKIT : "https://github.com/argmaxinc/WhisperKit" ,
472+ ENGINE_FASTER_WHISPER : "https://github.com/SYSTRAN/faster-whisper" ,
473+ ENGINE_MOONSHINE : "https://github.com/moonshine-ai/moonshine" ,
474+ ENGINE_SHERPA_ONNX : "https://github.com/k2-fsa/sherpa-onnx" ,
475+ ENGINE_MLX_AUDIO : "https://github.com/Blaizzy/mlx-audio" ,
476+ }
477+
478+ _SOURCE_LABEL_URLS = {
479+ "whisper.cpp" : "https://github.com/ggml-org/whisper.cpp" ,
480+ "faster-whisper" : "https://github.com/SYSTRAN/faster-whisper" ,
481+ "WhisperKit" : "https://github.com/argmaxinc/WhisperKit" ,
482+ "Moonshine Voice" : "https://github.com/moonshine-ai/moonshine" ,
483+ "sherpa-onnx" : "https://github.com/k2-fsa/sherpa-onnx" ,
484+ "MLX Audio" : "https://github.com/Blaizzy/mlx-audio" ,
485+ # Hosted on Handy's CDN; the product page is the right "source", not whisper.cpp.
486+ "Handy-compatible" : "https://handy.computer" ,
487+ "Breeze ASR" : "https://huggingface.co/MediaTek-Research/Breeze-ASR-25" ,
488+ }
489+
490+
422491def language_names (codes : tuple [str , ...]) -> list [str ]:
423492 """Human-readable names for a model's languages, in the order declared."""
424493 return [LANGUAGE_NAMES .get (code , code ) for code in codes ]
@@ -577,9 +646,8 @@ def language_names(codes: tuple[str, ...]) -> list[str]:
577646 language_codes = ("en" ,),
578647 family = "Parakeet TDT" ,
579648 description = (
580- "The English-only Parakeet. v3 traded English accuracy for 25-language coverage, so "
581- "this earlier release still transcribes English more accurately than the v3 entry "
582- "above at the same speed."
649+ "The English-only Parakeet. v3 trades some English accuracy for 25-language coverage, "
650+ "so this earlier release still transcribes English more accurately at the same speed."
583651 ),
584652 license_name = "CC BY 4.0" ,
585653 ),
@@ -657,9 +725,8 @@ def language_names(codes: tuple[str, ...]) -> list[str]:
657725 language_codes = ("en" ,),
658726 family = "Zipformer" ,
659727 description = (
660- "A small streaming-capable zipformer transducer. Unlike the other sherpa-onnx "
661- "models above, this one decodes incrementally over /v1/stream with real partial "
662- "results, independent of Moonshine."
728+ "A small streaming-capable zipformer transducer. Unlike most batch sherpa-onnx "
729+ "models, this one decodes incrementally with real partial results while you speak."
663730 ),
664731 license_name = "Apache 2.0" ,
665732 supports_streaming = True ,
@@ -803,8 +870,8 @@ def language_names(codes: tuple[str, ...]) -> list[str]:
803870 repository = "mlx-community/parakeet-tdt-0.6b-v2" ,
804871 family = "Parakeet TDT / MLX" ,
805872 description = (
806- "The English-only Parakeet on Apple silicon. More accurate on English than the v3 "
807- "entry above , which spends capacity on 24 other languages."
873+ "The English-only Parakeet on Apple silicon. More accurate on English than the "
874+ "multilingual v3 build , which spends capacity on 24 other languages."
808875 ),
809876 license_name = "CC BY 4.0" ,
810877 language_codes = ("en" ,),
@@ -980,8 +1047,13 @@ def language_names(codes: tuple[str, ...]) -> list[str]:
9801047 "Accurate · compact" ,
9811048 8 ,
9821049 download_url = "https://blob.handy.computer/whisper-medium-q4_1.bin" ,
983- description = "Handy's compact Whisper Medium build, usable without the Handy app." ,
1050+ description = (
1051+ "Handy's compact quantized Whisper Medium (Q4). Same whisper.cpp runtime; weights "
1052+ "are hosted on Handy's CDN and work without the Handy app."
1053+ ),
9841054 source = "Handy-compatible" ,
1055+ # MIT Whisper weights; Handy redistributes the quant.
1056+ # License string left generic so the UI links through to Handy rather than inventing one.
9851057 ),
9861058 _whisper_cpp (
9871059 "ggml-large-v3-turbo.bin" ,
@@ -999,7 +1071,10 @@ def language_names(codes: tuple[str, ...]) -> list[str]:
9991071 "Most accurate · compact" ,
10001072 16 ,
10011073 download_url = "https://blob.handy.computer/ggml-large-v3-q5_0.bin" ,
1002- description = "Quantized Whisper Large v3 from Handy's standalone model catalog." ,
1074+ description = (
1075+ "Quantized Whisper Large v3 (Q5) from Handy's model catalog. Larger and more accurate "
1076+ "than Medium Q4; still runs through the local whisper.cpp engine."
1077+ ),
10031078 source = "Handy-compatible" ,
10041079 ),
10051080 _whisper_cpp (
@@ -1011,9 +1086,14 @@ def language_names(codes: tuple[str, ...]) -> list[str]:
10111086 16 ,
10121087 download_url = "https://blob.handy.computer/breeze-asr-q5_k.bin" ,
10131088 family = "Breeze ASR" ,
1014- description = "Whisper variant tuned for Taiwanese Mandarin and code-switching." ,
1015- source = "Handy-compatible" ,
1089+ description = (
1090+ "MediaTek Breeze-ASR (Whisper Large v2 fine-tune) quantized to Q5 for whisper.cpp. "
1091+ "Tuned for Taiwanese Mandarin and Mandarin–English code-switching; "
1092+ "weights redistributed via Handy's CDN."
1093+ ),
1094+ source = "Breeze ASR" ,
10161095 language_codes = ("zh" , "en" ),
1096+ license_name = "Apache 2.0" ,
10171097 ),
10181098 _whisper_cpp (
10191099 "ggml-large-v3.bin" , "whisper.cpp Large v3" , 3 * GB , "Multilingual" , "Most accurate" , 24
0 commit comments