refactor(stt): openai-availability reason helper, one-line section banners, docstring compaction
This commit is contained in:
@@ -4,9 +4,8 @@ Binary discovery, the shared ffmpeg m4a encode (transcode + silence trim),
|
||||
source/format validation, WeChat .silk decoding, CAF conversion and the
|
||||
best-effort cloud pre-upload silence trim.
|
||||
|
||||
Split out of ``tools/transcription_tools.py``; moved names are re-imported
|
||||
there so ``tools.transcription_tools.<name>`` keeps resolving and patches on the
|
||||
origin still intercept (origin helpers are imported lazily inside functions).
|
||||
Split out of ``tools/transcription_tools.py``, which re-imports every name (patch
|
||||
surface) and is imported lazily here so origin patches still intercept.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -220,9 +219,7 @@ def _convert_caf_to_wav(file_path: str) -> Optional[str]:
|
||||
return None
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Cloud pre-upload silence trim
|
||||
# ---------------------------------------------------------------------------
|
||||
# ---- Cloud pre-upload silence trim --------------------------------------
|
||||
#
|
||||
# Local faster-whisper gets Silero VAD; cloud providers get the raw file, so
|
||||
# every second of silence is paid for twice (upload + per-minute billing) and
|
||||
|
||||
@@ -4,9 +4,8 @@ OpenAI-SDK-shaped backends (groq, openai, deepinfra), Mistral Voxtral, the REST
|
||||
multipart backends (xAI, ElevenLabs), and OpenAI audio credential resolution
|
||||
(config > keyless local server > env > managed Nous gateway).
|
||||
|
||||
Split out of ``tools/transcription_tools.py``; moved names are re-imported
|
||||
there so ``tools.transcription_tools.<name>`` keeps resolving and patches on the
|
||||
origin still intercept (origin helpers are imported lazily inside functions).
|
||||
Split out of ``tools/transcription_tools.py``, which re-imports every name (patch
|
||||
surface) and is imported lazily here so origin patches still intercept.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -4,9 +4,8 @@
|
||||
``TranscriptionProvider`` dispatch, and the ``pre_transcription`` hook that
|
||||
threads prompt/language/model overrides into every backend.
|
||||
|
||||
Split out of ``tools/transcription_tools.py``; moved names are re-imported
|
||||
there so ``tools.transcription_tools.<name>`` keeps resolving and patches on the
|
||||
origin still intercept (origin helpers are imported lazily inside functions).
|
||||
Split out of ``tools/transcription_tools.py``, which re-imports every name (patch
|
||||
surface) and is imported lazily here so origin patches still intercept.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -30,9 +29,7 @@ from tools.transcription_common import (
|
||||
logger = logging.getLogger("tools.transcription_tools")
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Command-provider registry (``stt.providers.<name>: type: command``)
|
||||
# ---------------------------------------------------------------------------
|
||||
# ---- Command-provider registry (``stt.providers.<name>: type: command``) ---
|
||||
#
|
||||
# Mirrors the TTS command-provider registry: same placeholder grammar,
|
||||
# shell-quote-aware rendering and process-tree termination on timeout.
|
||||
|
||||
@@ -5,9 +5,8 @@ anti-hallucination transcribe kwargs and segment gate, and the local whisper CLI
|
||||
(``local_command``) provider. The cached-model singleton and its idle-unload
|
||||
watcher stay in ``transcription_tools`` (they own the module state).
|
||||
|
||||
Split out of ``tools/transcription_tools.py``; moved names are re-imported
|
||||
there so ``tools.transcription_tools.<name>`` keeps resolving and patches on the
|
||||
origin still intercept (origin helpers are imported lazily inside functions).
|
||||
Split out of ``tools/transcription_tools.py``, which re-imports every name (patch
|
||||
surface) and is imported lazily here so origin patches still intercept.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -127,9 +127,7 @@ _idle_unload_mgmt_lock = threading.Lock()
|
||||
_IDLE_UNLOAD_CHECK_INTERVAL = 30 # seconds between idle checks
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Config helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
# ---- Config helpers -----------------------------------------------------
|
||||
|
||||
|
||||
def _load_stt_config() -> dict:
|
||||
@@ -173,13 +171,17 @@ def _resolve_stt_language(
|
||||
return None
|
||||
|
||||
|
||||
def _has_openai_audio_backend() -> bool:
|
||||
"""Return True when OpenAI audio can use config credentials, env credentials, or the managed gateway."""
|
||||
def _openai_audio_unavailable_reason() -> Optional[str]:
|
||||
"""None when OpenAI audio has usable credentials (config, env, or managed gateway); else the reason."""
|
||||
try:
|
||||
_resolve_openai_audio_client_config()
|
||||
return True
|
||||
except ValueError:
|
||||
return False
|
||||
return None
|
||||
except ValueError as exc:
|
||||
return str(exc)
|
||||
|
||||
|
||||
def _has_openai_audio_backend() -> bool:
|
||||
return _openai_audio_unavailable_reason() is None
|
||||
|
||||
|
||||
def _is_local_stt_provider(provider: str, stt_config: Dict[str, Any]) -> bool:
|
||||
@@ -187,9 +189,7 @@ def _is_local_stt_provider(provider: str, stt_config: Dict[str, Any]) -> bool:
|
||||
return (provider or "").lower().strip() in {"local", "local_command"}
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Provider resolution
|
||||
# ---------------------------------------------------------------------------
|
||||
# ---- Provider resolution ------------------------------------------------
|
||||
|
||||
|
||||
def _has_xai_stt_credentials_quietly() -> bool:
|
||||
@@ -223,12 +223,11 @@ def _resolve_explicit_openai() -> str:
|
||||
# Resolve directly rather than via the boolean probe so a managed
|
||||
# openai-audio gateway outage is logged with its real reason, not a
|
||||
# generic "no API key" hint.
|
||||
try:
|
||||
_resolve_openai_audio_client_config()
|
||||
reason = _openai_audio_unavailable_reason()
|
||||
if reason is None:
|
||||
return "openai"
|
||||
except ValueError as exc:
|
||||
logger.warning("STT provider 'openai' configured but unavailable: %s", exc)
|
||||
return "none"
|
||||
logger.warning("STT provider 'openai' configured but unavailable: %s", reason)
|
||||
return "none"
|
||||
|
||||
|
||||
def _detect_local_backend() -> Optional[str]:
|
||||
@@ -374,9 +373,7 @@ def _get_provider(stt_config: dict) -> str:
|
||||
return "none"
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Provider: local (faster-whisper)
|
||||
# ---------------------------------------------------------------------------
|
||||
# ---- Provider: local (faster-whisper) -----------------------------------
|
||||
|
||||
|
||||
def _unload_local_model() -> None:
|
||||
@@ -537,9 +534,7 @@ def _transcribe_local(
|
||||
return _error_result(f"Local transcription failed: {e}")
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Public API
|
||||
# ---------------------------------------------------------------------------
|
||||
# ---- Public API ---------------------------------------------------------
|
||||
|
||||
|
||||
def _read_block_error(file_path: str) -> Optional[Dict[str, Any]]:
|
||||
@@ -702,10 +697,9 @@ def _no_provider_error(provider: str, stt_config: Dict[str, Any]) -> Dict[str, A
|
||||
# selection-specific reason (e.g. managed openai-audio gateway down);
|
||||
# surface it with its remediation instead of the all-provider hint.
|
||||
if provider_key == "none" and str(stt_config.get("provider") or "") == "openai" and _HAS_OPENAI:
|
||||
try:
|
||||
_resolve_openai_audio_client_config()
|
||||
except ValueError as exc:
|
||||
return _error_result(str(exc))
|
||||
reason = _openai_audio_unavailable_reason()
|
||||
if reason is not None:
|
||||
return _error_result(reason)
|
||||
|
||||
return _error_result(
|
||||
"No STT provider available. Install faster-whisper for free local "
|
||||
|
||||
Reference in New Issue
Block a user