mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-29 18:46:59 +00:00
fix(qqbot): always clean up temp stt wav
This commit is contained in:
parent
fef1b8cbbe
commit
a2d8d3afc5
2 changed files with 75 additions and 7 deletions
|
|
@ -1936,15 +1936,15 @@ class QQAdapter(BasePlatformAdapter):
|
|||
)
|
||||
return None
|
||||
|
||||
# 4. Call STT API
|
||||
# 4. Call STT API and always clean up the temp WAV afterward.
|
||||
logger.debug("[%s] STT: calling ASR on %s", self._log_tag, wav_path)
|
||||
transcript = await self._call_stt(wav_path)
|
||||
|
||||
# 5. Cleanup temp file
|
||||
try:
|
||||
os.unlink(wav_path)
|
||||
except OSError:
|
||||
pass
|
||||
transcript = await self._call_stt(wav_path)
|
||||
finally:
|
||||
try:
|
||||
os.unlink(wav_path)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
if transcript:
|
||||
logger.debug("[%s] STT success: %r", self._log_tag, transcript[:100])
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import os
|
|||
from types import SimpleNamespace
|
||||
from unittest import mock
|
||||
|
||||
import httpx
|
||||
import pytest
|
||||
|
||||
from gateway.config import PlatformConfig
|
||||
|
|
@ -215,6 +216,73 @@ class TestVoiceAttachmentSSRFProtection:
|
|||
assert connected_explicit is False
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Voice attachment temp-file cleanup
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
class TestVoiceAttachmentTempCleanup:
|
||||
def _make_adapter(self, **extra):
|
||||
from gateway.platforms.qqbot import QQAdapter
|
||||
return QQAdapter(_make_config(**extra))
|
||||
|
||||
def _setup_download_mocks(self, adapter, content=b"RIFFmock-wav-audio-data"):
|
||||
response = mock.Mock()
|
||||
response.content = content
|
||||
response.headers = {"content-type": "audio/wav"}
|
||||
response.raise_for_status = mock.Mock()
|
||||
|
||||
adapter._http_client = mock.AsyncMock()
|
||||
adapter._http_client.get = mock.AsyncMock(return_value=response)
|
||||
|
||||
def test_temp_wav_cleaned_up_on_stt_failure(self):
|
||||
adapter = self._make_adapter(app_id="a", client_secret="b")
|
||||
self._setup_download_mocks(adapter)
|
||||
seen = {}
|
||||
|
||||
async def _raise_transport_error(path):
|
||||
seen["wav_path"] = path
|
||||
raise httpx.TransportError("boom")
|
||||
|
||||
with mock.patch("tools.url_safety.is_safe_url", return_value=True):
|
||||
adapter._call_stt = mock.AsyncMock(side_effect=_raise_transport_error)
|
||||
transcript = asyncio.run(
|
||||
adapter._stt_voice_attachment(
|
||||
"https://cdn.qq.com/voice.silk",
|
||||
"audio/silk",
|
||||
"voice.silk",
|
||||
voice_wav_url="https://cdn.qq.com/voice.wav",
|
||||
)
|
||||
)
|
||||
|
||||
assert transcript is None
|
||||
assert "wav_path" in seen
|
||||
assert not os.path.exists(seen["wav_path"])
|
||||
|
||||
def test_temp_wav_cleaned_up_on_stt_success(self):
|
||||
adapter = self._make_adapter(app_id="a", client_secret="b")
|
||||
self._setup_download_mocks(adapter)
|
||||
seen = {}
|
||||
|
||||
async def _return_transcript(path):
|
||||
seen["wav_path"] = path
|
||||
return "hello from qq voice"
|
||||
|
||||
with mock.patch("tools.url_safety.is_safe_url", return_value=True):
|
||||
adapter._call_stt = mock.AsyncMock(side_effect=_return_transcript)
|
||||
transcript = asyncio.run(
|
||||
adapter._stt_voice_attachment(
|
||||
"https://cdn.qq.com/voice.silk",
|
||||
"audio/silk",
|
||||
"voice.silk",
|
||||
voice_wav_url="https://cdn.qq.com/voice.wav",
|
||||
)
|
||||
)
|
||||
|
||||
assert transcript == "hello from qq voice"
|
||||
assert "wav_path" in seen
|
||||
assert not os.path.exists(seen["wav_path"])
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# WebSocket proxy handling
|
||||
# ---------------------------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue