mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-29 18:46:59 +00:00
fix(voice): honor forwarded audio (PIPEWIRE_REMOTE) in WSL detection
This commit is contained in:
parent
2a75664c0c
commit
ef686c3878
2 changed files with 68 additions and 8 deletions
58
tests/tools/test_voice_wsl_pipewire.py
Normal file
58
tests/tools/test_voice_wsl_pipewire.py
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
"""Regression: WSL voice detection must honor PIPEWIRE_REMOTE, not only PULSE_SERVER.
|
||||
|
||||
detect_audio_environment() honors forwarded audio (has_forwarded_audio =
|
||||
PULSE_SERVER or PIPEWIRE_REMOTE or a reachable socket) in the SSH and container
|
||||
blocks, but the WSL block previously checked only PULSE_SERVER — so a WSL user
|
||||
with PipeWire forwarding (PIPEWIRE_REMOTE) was wrongly blocked from voice mode.
|
||||
These tests mock /proc/version so they reproduce the WSL path on any host.
|
||||
"""
|
||||
import builtins
|
||||
import io
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
WSL = "Linux version 5.15.0-microsoft-standard-WSL2 (oe-user@oe-host)"
|
||||
|
||||
|
||||
def _force_wsl(monkeypatch, content=WSL):
|
||||
real_open = builtins.open
|
||||
def fake_open(file, *a, **k):
|
||||
if str(file) == "/proc/version":
|
||||
return io.StringIO(content)
|
||||
return real_open(file, *a, **k)
|
||||
monkeypatch.setattr(builtins, "open", fake_open)
|
||||
|
||||
|
||||
def _base(monkeypatch):
|
||||
for v in ("SSH_CLIENT", "SSH_TTY", "SSH_CONNECTION", "PULSE_SERVER"):
|
||||
monkeypatch.delenv(v, raising=False)
|
||||
monkeypatch.delenv("PIPEWIRE_REMOTE", raising=False)
|
||||
monkeypatch.setattr("hermes_constants.is_container", lambda: False)
|
||||
monkeypatch.setattr("tools.voice_mode._pulse_socket_reachable", lambda: False)
|
||||
sd = MagicMock(); sd.query_devices.return_value = [{"name": "dev"}]
|
||||
monkeypatch.setattr("tools.voice_mode._import_audio", lambda: (sd, MagicMock()))
|
||||
|
||||
|
||||
def test_wsl_with_pipewire_remote_allows_voice(monkeypatch):
|
||||
_base(monkeypatch)
|
||||
monkeypatch.setenv("PIPEWIRE_REMOTE", "/run/user/1000/pipewire-0")
|
||||
_force_wsl(monkeypatch)
|
||||
from tools.voice_mode import detect_audio_environment
|
||||
result = detect_audio_environment()
|
||||
assert result["available"] is True, result["warnings"]
|
||||
|
||||
|
||||
def test_wsl_with_pulse_server_still_allows_voice(monkeypatch):
|
||||
_base(monkeypatch)
|
||||
monkeypatch.setenv("PULSE_SERVER", "unix:/mnt/wslg/PulseServer")
|
||||
_force_wsl(monkeypatch)
|
||||
from tools.voice_mode import detect_audio_environment
|
||||
assert detect_audio_environment()["available"] is True
|
||||
|
||||
|
||||
def test_wsl_without_forwarding_still_blocks(monkeypatch):
|
||||
_base(monkeypatch)
|
||||
_force_wsl(monkeypatch) # no PULSE_SERVER, no PIPEWIRE_REMOTE
|
||||
from tools.voice_mode import detect_audio_environment
|
||||
res = detect_audio_environment()
|
||||
assert res["available"] is False
|
||||
assert any("WSL" in w for w in res["warnings"])
|
||||
|
|
@ -207,19 +207,21 @@ def detect_audio_environment() -> dict:
|
|||
" PipeWire: -e PIPEWIRE_REMOTE=$XDG_RUNTIME_DIR/pipewire-0"
|
||||
)
|
||||
|
||||
# WSL detection — PulseAudio bridge makes audio work in WSL.
|
||||
# Only block if PULSE_SERVER is not configured.
|
||||
# WSL detection — a reachable sound server makes audio work in WSL.
|
||||
# Honor any forwarding (PulseAudio bridge OR a forwarded PipeWire/Pulse
|
||||
# socket), mirroring the SSH and container blocks above. Only block when
|
||||
# no forwarding is configured.
|
||||
try:
|
||||
with open('/proc/version', 'r', encoding="utf-8") as f:
|
||||
if 'microsoft' in f.read().lower():
|
||||
if os.environ.get('PULSE_SERVER'):
|
||||
notices.append("Running in WSL with PulseAudio bridge")
|
||||
if has_forwarded_audio:
|
||||
notices.append("Running in WSL with a reachable PulseAudio/PipeWire sound server")
|
||||
else:
|
||||
warnings.append(
|
||||
"Running in WSL -- audio requires PulseAudio bridge.\n"
|
||||
" 1. Set PULSE_SERVER=unix:/mnt/wslg/PulseServer\n"
|
||||
" 2. Create ~/.asoundrc pointing ALSA at PulseAudio\n"
|
||||
" 3. Verify with: arecord -d 3 /tmp/test.wav && aplay /tmp/test.wav"
|
||||
"Running in WSL -- audio requires a forwarded sound server.\n"
|
||||
" PulseAudio: export PULSE_SERVER=unix:/mnt/wslg/PulseServer\n"
|
||||
" PipeWire: export PIPEWIRE_REMOTE=$XDG_RUNTIME_DIR/pipewire-0\n"
|
||||
" Then verify: arecord -d 3 /tmp/test.wav && aplay /tmp/test.wav"
|
||||
)
|
||||
except (FileNotFoundError, PermissionError, OSError):
|
||||
pass
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue