test(voice): clarify install guidance and local skips
Add an explicit messaging-extra install hint to the missing PyNaCl/davey error path, cover it with a voice-channel join regression test, and skip the low-level NaCl packet tests when PyNaCl is not installed locally.
This commit is contained in:
parent
5f32fd8b6d
commit
2d57946ee9
2 changed files with 33 additions and 4 deletions
|
|
@ -2437,7 +2437,11 @@ class GatewayRunner:
|
||||||
adapter._voice_input_callback = None
|
adapter._voice_input_callback = None
|
||||||
err_lower = str(e).lower()
|
err_lower = str(e).lower()
|
||||||
if "pynacl" in err_lower or "nacl" in err_lower or "davey" in err_lower:
|
if "pynacl" in err_lower or "nacl" in err_lower or "davey" in err_lower:
|
||||||
return "Voice dependencies are missing (PyNaCl / davey). Please reinstall Hermes with voice support enabled."
|
return (
|
||||||
|
"Voice dependencies are missing (PyNaCl / davey). "
|
||||||
|
"Install or reinstall Hermes with the messaging extra, e.g. "
|
||||||
|
"`pip install hermes-agent[messaging]`."
|
||||||
|
)
|
||||||
return f"Failed to join voice channel: {e}"
|
return f"Failed to join voice channel: {e}"
|
||||||
|
|
||||||
if success:
|
if success:
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
"""Tests for the /voice command and auto voice reply in the gateway."""
|
"""Tests for the /voice command and auto voice reply in the gateway."""
|
||||||
|
|
||||||
|
import importlib.util
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import queue
|
import queue
|
||||||
|
|
@ -206,9 +207,11 @@ class TestAutoVoiceReply:
|
||||||
2. gateway _send_voice_reply: fires based on voice_mode setting
|
2. gateway _send_voice_reply: fires based on voice_mode setting
|
||||||
|
|
||||||
To prevent double audio, _send_voice_reply is skipped when voice input
|
To prevent double audio, _send_voice_reply is skipped when voice input
|
||||||
already triggered base adapter auto-TTS (skip_double = is_voice_input).
|
already triggered base adapter auto-TTS.
|
||||||
Exception: Discord voice channel — both auto-TTS and Discord play_tts
|
|
||||||
override skip, so the runner must handle it via play_in_voice_channel.
|
For Discord voice channels, the base adapter now routes play_tts directly
|
||||||
|
into VC playback, so the runner should still skip voice-input follow-ups to
|
||||||
|
avoid double playback.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
|
|
@ -734,6 +737,24 @@ class TestVoiceChannelCommands:
|
||||||
result = await runner._handle_voice_channel_join(event)
|
result = await runner._handle_voice_channel_join(event)
|
||||||
assert "failed" in result.lower()
|
assert "failed" in result.lower()
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_join_missing_voice_dependencies(self, runner):
|
||||||
|
"""Missing PyNaCl/davey should return a user-actionable install hint."""
|
||||||
|
mock_channel = MagicMock()
|
||||||
|
mock_channel.name = "General"
|
||||||
|
mock_adapter = AsyncMock()
|
||||||
|
mock_adapter.join_voice_channel = AsyncMock(
|
||||||
|
side_effect=RuntimeError("PyNaCl library needed in order to use voice")
|
||||||
|
)
|
||||||
|
mock_adapter.get_user_voice_channel = AsyncMock(return_value=mock_channel)
|
||||||
|
event = self._make_discord_event()
|
||||||
|
runner.adapters[event.source.platform] = mock_adapter
|
||||||
|
|
||||||
|
result = await runner._handle_voice_channel_join(event)
|
||||||
|
|
||||||
|
assert "voice dependencies are missing" in result.lower()
|
||||||
|
assert "hermes-agent[messaging]" in result
|
||||||
|
|
||||||
# -- _handle_voice_channel_leave --
|
# -- _handle_voice_channel_leave --
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
|
|
@ -2044,6 +2065,10 @@ class TestDisconnectVoiceCleanup:
|
||||||
# =====================================================================
|
# =====================================================================
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skipif(
|
||||||
|
importlib.util.find_spec("nacl") is None,
|
||||||
|
reason="PyNaCl not installed",
|
||||||
|
)
|
||||||
class TestVoiceReception:
|
class TestVoiceReception:
|
||||||
"""Audio reception: SSRC mapping, DAVE passthrough, buffer lifecycle."""
|
"""Audio reception: SSRC mapping, DAVE passthrough, buffer lifecycle."""
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue