mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-29 01:31:41 +00:00
fix: address PR review round 4 — remove web UI, fix audio/import/interface issues
Remove web UI gateway (web.py, tests, docs, toolset, env vars, Platform.WEB enum) per maintainer request — Nous is building their own official chat UI. Fix 1: Replace sd.wait() with polling pattern in play_audio_file() to prevent indefinite hang when audio device stalls (consistent with play_beep()). Fix 2: Use importlib.util.find_spec() for faster_whisper/openai availability checks instead of module-level imports that trigger heavy native library loading (CUDA/cuDNN) at import time. Fix 3: Remove inspect.signature() hack in _send_voice_reply() — add **kwargs to Telegram send_voice() so all adapters accept metadata uniformly. Fix 4: Make session loading resilient to removed platform enum values — skip entries with unknown platforms instead of crashing the entire gateway.
This commit is contained in:
parent
1ad5e0ed15
commit
35748a2fb0
17 changed files with 55 additions and 2930 deletions
|
|
@ -125,7 +125,7 @@ class TestTranscribeLocal:
|
|||
mock_model.transcribe.return_value = ([mock_segment], mock_info)
|
||||
|
||||
with patch("tools.transcription_tools._HAS_FASTER_WHISPER", True), \
|
||||
patch("tools.transcription_tools.WhisperModel", return_value=mock_model), \
|
||||
patch("faster_whisper.WhisperModel", return_value=mock_model), \
|
||||
patch("tools.transcription_tools._local_model", None):
|
||||
from tools.transcription_tools import _transcribe_local
|
||||
result = _transcribe_local(str(audio_file), "base")
|
||||
|
|
@ -164,7 +164,7 @@ class TestTranscribeOpenAI:
|
|||
mock_client.audio.transcriptions.create.return_value = "Hello from OpenAI"
|
||||
|
||||
with patch("tools.transcription_tools._HAS_OPENAI", True), \
|
||||
patch("tools.transcription_tools.OpenAI", return_value=mock_client):
|
||||
patch("openai.OpenAI", return_value=mock_client):
|
||||
from tools.transcription_tools import _transcribe_openai
|
||||
result = _transcribe_openai(str(audio_file), "whisper-1")
|
||||
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ class TestTranscribeGroq:
|
|||
mock_client.audio.transcriptions.create.return_value = "hello world"
|
||||
|
||||
with patch("tools.transcription_tools._HAS_OPENAI", True), \
|
||||
patch("tools.transcription_tools.OpenAI", return_value=mock_client):
|
||||
patch("openai.OpenAI", return_value=mock_client):
|
||||
from tools.transcription_tools import _transcribe_groq
|
||||
result = _transcribe_groq(sample_wav, "whisper-large-v3-turbo")
|
||||
|
||||
|
|
@ -175,7 +175,7 @@ class TestTranscribeGroq:
|
|||
mock_client.audio.transcriptions.create.return_value = " hello world \n"
|
||||
|
||||
with patch("tools.transcription_tools._HAS_OPENAI", True), \
|
||||
patch("tools.transcription_tools.OpenAI", return_value=mock_client):
|
||||
patch("openai.OpenAI", return_value=mock_client):
|
||||
from tools.transcription_tools import _transcribe_groq
|
||||
result = _transcribe_groq(sample_wav, "whisper-large-v3-turbo")
|
||||
|
||||
|
|
@ -188,7 +188,7 @@ class TestTranscribeGroq:
|
|||
mock_client.audio.transcriptions.create.return_value = "test"
|
||||
|
||||
with patch("tools.transcription_tools._HAS_OPENAI", True), \
|
||||
patch("tools.transcription_tools.OpenAI", return_value=mock_client) as mock_openai_cls:
|
||||
patch("openai.OpenAI", return_value=mock_client) as mock_openai_cls:
|
||||
from tools.transcription_tools import _transcribe_groq, GROQ_BASE_URL
|
||||
_transcribe_groq(sample_wav, "whisper-large-v3-turbo")
|
||||
|
||||
|
|
@ -202,7 +202,7 @@ class TestTranscribeGroq:
|
|||
mock_client.audio.transcriptions.create.side_effect = Exception("API error")
|
||||
|
||||
with patch("tools.transcription_tools._HAS_OPENAI", True), \
|
||||
patch("tools.transcription_tools.OpenAI", return_value=mock_client):
|
||||
patch("openai.OpenAI", return_value=mock_client):
|
||||
from tools.transcription_tools import _transcribe_groq
|
||||
result = _transcribe_groq(sample_wav, "whisper-large-v3-turbo")
|
||||
|
||||
|
|
@ -216,7 +216,7 @@ class TestTranscribeGroq:
|
|||
mock_client.audio.transcriptions.create.side_effect = PermissionError("denied")
|
||||
|
||||
with patch("tools.transcription_tools._HAS_OPENAI", True), \
|
||||
patch("tools.transcription_tools.OpenAI", return_value=mock_client):
|
||||
patch("openai.OpenAI", return_value=mock_client):
|
||||
from tools.transcription_tools import _transcribe_groq
|
||||
result = _transcribe_groq(sample_wav, "whisper-large-v3-turbo")
|
||||
|
||||
|
|
@ -244,7 +244,7 @@ class TestTranscribeOpenAIExtended:
|
|||
mock_client.audio.transcriptions.create.return_value = "test"
|
||||
|
||||
with patch("tools.transcription_tools._HAS_OPENAI", True), \
|
||||
patch("tools.transcription_tools.OpenAI", return_value=mock_client) as mock_openai_cls:
|
||||
patch("openai.OpenAI", return_value=mock_client) as mock_openai_cls:
|
||||
from tools.transcription_tools import _transcribe_openai, OPENAI_BASE_URL
|
||||
_transcribe_openai(sample_wav, "whisper-1")
|
||||
|
||||
|
|
@ -258,7 +258,7 @@ class TestTranscribeOpenAIExtended:
|
|||
mock_client.audio.transcriptions.create.return_value = " hello \n"
|
||||
|
||||
with patch("tools.transcription_tools._HAS_OPENAI", True), \
|
||||
patch("tools.transcription_tools.OpenAI", return_value=mock_client):
|
||||
patch("openai.OpenAI", return_value=mock_client):
|
||||
from tools.transcription_tools import _transcribe_openai
|
||||
result = _transcribe_openai(sample_wav, "whisper-1")
|
||||
|
||||
|
|
@ -271,7 +271,7 @@ class TestTranscribeOpenAIExtended:
|
|||
mock_client.audio.transcriptions.create.side_effect = PermissionError("denied")
|
||||
|
||||
with patch("tools.transcription_tools._HAS_OPENAI", True), \
|
||||
patch("tools.transcription_tools.OpenAI", return_value=mock_client):
|
||||
patch("openai.OpenAI", return_value=mock_client):
|
||||
from tools.transcription_tools import _transcribe_openai
|
||||
result = _transcribe_openai(sample_wav, "whisper-1")
|
||||
|
||||
|
|
@ -300,7 +300,7 @@ class TestTranscribeLocalExtended:
|
|||
mock_whisper_cls = MagicMock(return_value=mock_model)
|
||||
|
||||
with patch("tools.transcription_tools._HAS_FASTER_WHISPER", True), \
|
||||
patch("tools.transcription_tools.WhisperModel", mock_whisper_cls), \
|
||||
patch("faster_whisper.WhisperModel", mock_whisper_cls), \
|
||||
patch("tools.transcription_tools._local_model", None), \
|
||||
patch("tools.transcription_tools._local_model_name", None):
|
||||
from tools.transcription_tools import _transcribe_local
|
||||
|
|
@ -326,7 +326,7 @@ class TestTranscribeLocalExtended:
|
|||
mock_whisper_cls = MagicMock(return_value=mock_model)
|
||||
|
||||
with patch("tools.transcription_tools._HAS_FASTER_WHISPER", True), \
|
||||
patch("tools.transcription_tools.WhisperModel", mock_whisper_cls), \
|
||||
patch("faster_whisper.WhisperModel", mock_whisper_cls), \
|
||||
patch("tools.transcription_tools._local_model", None), \
|
||||
patch("tools.transcription_tools._local_model_name", None):
|
||||
from tools.transcription_tools import _transcribe_local
|
||||
|
|
@ -342,7 +342,7 @@ class TestTranscribeLocalExtended:
|
|||
mock_whisper_cls = MagicMock(side_effect=RuntimeError("CUDA out of memory"))
|
||||
|
||||
with patch("tools.transcription_tools._HAS_FASTER_WHISPER", True), \
|
||||
patch("tools.transcription_tools.WhisperModel", mock_whisper_cls), \
|
||||
patch("faster_whisper.WhisperModel", mock_whisper_cls), \
|
||||
patch("tools.transcription_tools._local_model", None):
|
||||
from tools.transcription_tools import _transcribe_local
|
||||
result = _transcribe_local(str(audio), "large-v3")
|
||||
|
|
@ -366,7 +366,7 @@ class TestTranscribeLocalExtended:
|
|||
mock_model.transcribe.return_value = ([seg1, seg2], mock_info)
|
||||
|
||||
with patch("tools.transcription_tools._HAS_FASTER_WHISPER", True), \
|
||||
patch("tools.transcription_tools.WhisperModel", return_value=mock_model), \
|
||||
patch("faster_whisper.WhisperModel", return_value=mock_model), \
|
||||
patch("tools.transcription_tools._local_model", None):
|
||||
from tools.transcription_tools import _transcribe_local
|
||||
result = _transcribe_local(str(audio), "base")
|
||||
|
|
@ -387,7 +387,7 @@ class TestModelAutoCorrection:
|
|||
mock_client.audio.transcriptions.create.return_value = "hello world"
|
||||
|
||||
with patch("tools.transcription_tools._HAS_OPENAI", True), \
|
||||
patch("tools.transcription_tools.OpenAI", return_value=mock_client):
|
||||
patch("openai.OpenAI", return_value=mock_client):
|
||||
from tools.transcription_tools import _transcribe_groq, DEFAULT_GROQ_STT_MODEL
|
||||
_transcribe_groq(sample_wav, "whisper-1")
|
||||
|
||||
|
|
@ -401,7 +401,7 @@ class TestModelAutoCorrection:
|
|||
mock_client.audio.transcriptions.create.return_value = "test"
|
||||
|
||||
with patch("tools.transcription_tools._HAS_OPENAI", True), \
|
||||
patch("tools.transcription_tools.OpenAI", return_value=mock_client):
|
||||
patch("openai.OpenAI", return_value=mock_client):
|
||||
from tools.transcription_tools import _transcribe_groq, DEFAULT_GROQ_STT_MODEL
|
||||
_transcribe_groq(sample_wav, "gpt-4o-transcribe")
|
||||
|
||||
|
|
@ -415,7 +415,7 @@ class TestModelAutoCorrection:
|
|||
mock_client.audio.transcriptions.create.return_value = "hello world"
|
||||
|
||||
with patch("tools.transcription_tools._HAS_OPENAI", True), \
|
||||
patch("tools.transcription_tools.OpenAI", return_value=mock_client):
|
||||
patch("openai.OpenAI", return_value=mock_client):
|
||||
from tools.transcription_tools import _transcribe_openai, DEFAULT_STT_MODEL
|
||||
_transcribe_openai(sample_wav, "whisper-large-v3-turbo")
|
||||
|
||||
|
|
@ -429,7 +429,7 @@ class TestModelAutoCorrection:
|
|||
mock_client.audio.transcriptions.create.return_value = "test"
|
||||
|
||||
with patch("tools.transcription_tools._HAS_OPENAI", True), \
|
||||
patch("tools.transcription_tools.OpenAI", return_value=mock_client):
|
||||
patch("openai.OpenAI", return_value=mock_client):
|
||||
from tools.transcription_tools import _transcribe_openai, DEFAULT_STT_MODEL
|
||||
_transcribe_openai(sample_wav, "distil-whisper-large-v3-en")
|
||||
|
||||
|
|
@ -443,7 +443,7 @@ class TestModelAutoCorrection:
|
|||
mock_client.audio.transcriptions.create.return_value = "test"
|
||||
|
||||
with patch("tools.transcription_tools._HAS_OPENAI", True), \
|
||||
patch("tools.transcription_tools.OpenAI", return_value=mock_client):
|
||||
patch("openai.OpenAI", return_value=mock_client):
|
||||
from tools.transcription_tools import _transcribe_groq
|
||||
_transcribe_groq(sample_wav, "whisper-large-v3")
|
||||
|
||||
|
|
@ -457,7 +457,7 @@ class TestModelAutoCorrection:
|
|||
mock_client.audio.transcriptions.create.return_value = "test"
|
||||
|
||||
with patch("tools.transcription_tools._HAS_OPENAI", True), \
|
||||
patch("tools.transcription_tools.OpenAI", return_value=mock_client):
|
||||
patch("openai.OpenAI", return_value=mock_client):
|
||||
from tools.transcription_tools import _transcribe_openai
|
||||
_transcribe_openai(sample_wav, "gpt-4o-mini-transcribe")
|
||||
|
||||
|
|
@ -472,7 +472,7 @@ class TestModelAutoCorrection:
|
|||
mock_client.audio.transcriptions.create.return_value = "test"
|
||||
|
||||
with patch("tools.transcription_tools._HAS_OPENAI", True), \
|
||||
patch("tools.transcription_tools.OpenAI", return_value=mock_client):
|
||||
patch("openai.OpenAI", return_value=mock_client):
|
||||
from tools.transcription_tools import _transcribe_groq
|
||||
_transcribe_groq(sample_wav, "my-custom-model")
|
||||
|
||||
|
|
@ -486,7 +486,7 @@ class TestModelAutoCorrection:
|
|||
mock_client.audio.transcriptions.create.return_value = "test"
|
||||
|
||||
with patch("tools.transcription_tools._HAS_OPENAI", True), \
|
||||
patch("tools.transcription_tools.OpenAI", return_value=mock_client):
|
||||
patch("openai.OpenAI", return_value=mock_client):
|
||||
from tools.transcription_tools import _transcribe_openai
|
||||
_transcribe_openai(sample_wav, "my-custom-model")
|
||||
|
||||
|
|
|
|||
|
|
@ -345,6 +345,10 @@ class TestPlayAudioFile:
|
|||
np = pytest.importorskip("numpy")
|
||||
|
||||
mock_sd_obj = MagicMock()
|
||||
# Simulate stream completing immediately (get_stream().active = False)
|
||||
mock_stream = MagicMock()
|
||||
mock_stream.active = False
|
||||
mock_sd_obj.get_stream.return_value = mock_stream
|
||||
|
||||
def _fake_import():
|
||||
return mock_sd_obj, np
|
||||
|
|
@ -357,7 +361,7 @@ class TestPlayAudioFile:
|
|||
|
||||
assert result is True
|
||||
mock_sd_obj.play.assert_called_once()
|
||||
mock_sd_obj.wait.assert_called_once()
|
||||
mock_sd_obj.stop.assert_called_once()
|
||||
|
||||
def test_returns_false_when_no_player(self, monkeypatch, sample_wav):
|
||||
def _fail_import():
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue