mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-29 18:46:59 +00:00
fix(stt): report unregistered configured providers
This commit is contained in:
parent
3290c18247
commit
a5074c0ca8
2 changed files with 53 additions and 12 deletions
|
|
@ -8,7 +8,7 @@ to #30398 — STT pluggability):
|
|||
built-in name (which the registry blocks), the dispatcher re-checks
|
||||
defensively.
|
||||
2. Unknown name with no plugin → returns None (caller surfaces the
|
||||
legacy "No STT provider available" error).
|
||||
"provider_not_registered" error).
|
||||
3. Unknown name with plugin registered → dispatches, returns result.
|
||||
4. Plugin exceptions are caught and converted to the standard error
|
||||
envelope.
|
||||
|
|
@ -235,10 +235,8 @@ class TestTranscribeAudioE2E:
|
|||
assert result["transcript"] == "fake transcript"
|
||||
assert result["provider"] == "openrouter"
|
||||
|
||||
def test_unknown_name_without_plugin_falls_to_legacy_error(self, sample_audio_file):
|
||||
"""When no plugin is registered for the unknown name, the
|
||||
dispatcher returns None and transcribe_audio falls through to
|
||||
the legacy 'No STT provider available' error message."""
|
||||
def test_unknown_name_without_plugin_returns_provider_specific_error(self, sample_audio_file):
|
||||
"""Explicit unknown providers should get a named registration error."""
|
||||
from unittest.mock import patch
|
||||
|
||||
with patch("tools.transcription_tools._load_stt_config", return_value={"provider": "openrouter"}), \
|
||||
|
|
@ -247,7 +245,25 @@ class TestTranscribeAudioE2E:
|
|||
result = transcription_tools.transcribe_audio(sample_audio_file)
|
||||
|
||||
assert result["success"] is False
|
||||
assert "No STT provider" in result["error"]
|
||||
assert result["provider"] == "openrouter"
|
||||
assert result["error_type"] == "provider_not_registered"
|
||||
assert "stt.provider='openrouter'" in result["error"]
|
||||
assert "hermes plugins list" in result["error"]
|
||||
assert "No STT provider available" not in result["error"]
|
||||
|
||||
def test_auto_detect_failure_keeps_legacy_no_provider_message(self):
|
||||
"""No explicit stt.provider remains the generic setup guidance path."""
|
||||
from unittest.mock import patch
|
||||
|
||||
with patch("tools.transcription_tools._validate_audio_file", return_value=None), \
|
||||
patch("tools.transcription_tools._load_stt_config", return_value={}), \
|
||||
patch("tools.transcription_tools.is_stt_enabled", return_value=True), \
|
||||
patch("tools.transcription_tools._get_provider", return_value="none"):
|
||||
result = transcription_tools.transcribe_audio("/tmp/audio.mp3")
|
||||
|
||||
assert result["success"] is False
|
||||
assert result.get("error_type") is None
|
||||
assert "No STT provider available" in result["error"]
|
||||
|
||||
def test_builtin_name_does_not_consult_plugin_registry(self, sample_audio_file):
|
||||
"""Even if a plugin's name collides with a built-in (which the
|
||||
|
|
|
|||
|
|
@ -949,6 +949,22 @@ def _get_provider(stt_config: dict) -> str:
|
|||
return "none"
|
||||
|
||||
|
||||
def _unregistered_stt_provider_error(provider: str) -> Dict[str, Any]:
|
||||
key = str(provider or "").strip()
|
||||
return {
|
||||
"success": False,
|
||||
"transcript": "",
|
||||
"provider": key,
|
||||
"error_type": "provider_not_registered",
|
||||
"error": (
|
||||
f"stt.provider='{key}' is set but no built-in, command, or plugin "
|
||||
"provider registered that name. Run `hermes plugins list` to see "
|
||||
"installed STT plugins, or configure a command provider under "
|
||||
f"`stt.providers.{key}.command`."
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Plugin provider dispatch (issue follow-up to #30398 — STT pluggability)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
|
@ -965,8 +981,8 @@ def _dispatch_to_plugin_provider(
|
|||
"""Route the call to a plugin-registered transcription provider, or
|
||||
return None.
|
||||
|
||||
Returns the transcribe-response dict on dispatch, or ``None`` to
|
||||
fall through to the legacy "No STT provider available" error path.
|
||||
Returns the transcribe-response dict on dispatch, or ``None`` when no
|
||||
plugin claimed the provider name.
|
||||
|
||||
Resolution invariants enforced here:
|
||||
|
||||
|
|
@ -984,8 +1000,8 @@ def _dispatch_to_plugin_provider(
|
|||
3. Plugin dispatch fires only when ``provider`` matches a
|
||||
registered :class:`TranscriptionProvider` whose ``name`` equals
|
||||
the configured value. Unknown names with no plugin registered
|
||||
return None (caller surfaces the legacy "No STT provider"
|
||||
message).
|
||||
return None (caller surfaces the configured-provider error when
|
||||
the name came from ``stt.provider``).
|
||||
4. Availability gating: when the matched plugin reports
|
||||
``is_available() == False`` (missing API key, missing optional
|
||||
SDK, etc.) this returns an error envelope identifying the
|
||||
|
|
@ -1983,8 +1999,8 @@ def transcribe_audio(file_path: str, model: Optional[str] = None) -> Dict[str, A
|
|||
# nor ``"none"`` AND there is no same-name command provider. The
|
||||
# dispatcher enforces built-ins-always-win + command-wins-over-plugin
|
||||
# defensively. Returns None when no plugin is registered for the
|
||||
# configured name, falling through to the legacy "No STT provider"
|
||||
# error message below.
|
||||
# configured name; explicit configured names get a provider-specific
|
||||
# error before the generic auto-detect fallback below.
|
||||
#
|
||||
# Plugin-scoped config namespace mirrors the built-in pattern
|
||||
# (``stt.openai.model``, ``stt.mistral.model``): plugins read their
|
||||
|
|
@ -2004,6 +2020,15 @@ def transcribe_audio(file_path: str, model: Optional[str] = None) -> Dict[str, A
|
|||
if plugin_result is not None:
|
||||
return plugin_result
|
||||
|
||||
provider_key = str(provider or "").strip().lower()
|
||||
if (
|
||||
"provider" in stt_config
|
||||
and provider_key
|
||||
and provider_key not in BUILTIN_STT_PROVIDERS
|
||||
and provider_key != "none"
|
||||
):
|
||||
return _unregistered_stt_provider_error(provider_key)
|
||||
|
||||
# No provider available
|
||||
return {
|
||||
"success": False,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue