mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-29 18:46:59 +00:00
fix(tools): chunk command TTS stream reads
This commit is contained in:
parent
3884f078bd
commit
1b97e3efc5
2 changed files with 54 additions and 7 deletions
|
|
@ -363,6 +363,39 @@ class TestRenderCommandTtsTemplate:
|
|||
# ---------------------------------------------------------------------------
|
||||
|
||||
class TestRunCommandTts:
|
||||
def test_reads_process_output_in_large_chunks(self):
|
||||
read_sizes: dict[str, list[int]] = {"stdout": [], "stderr": []}
|
||||
|
||||
class FakeStream:
|
||||
def __init__(self, name: str, chunks: list[str]):
|
||||
self.name = name
|
||||
self.chunks = chunks
|
||||
|
||||
def read(self, size: int) -> str:
|
||||
read_sizes[self.name].append(size)
|
||||
if self.chunks:
|
||||
return self.chunks.pop(0)
|
||||
return ""
|
||||
|
||||
class FakeProcess:
|
||||
def __init__(self):
|
||||
self.pid = 12345
|
||||
self.returncode = 0
|
||||
self.stdout = FakeStream("stdout", ["done"])
|
||||
self.stderr = FakeStream("stderr", ["tick"])
|
||||
|
||||
def wait(self, timeout=None):
|
||||
return self.returncode
|
||||
|
||||
with patch("tools.tts_tool.subprocess.Popen", return_value=FakeProcess()):
|
||||
result = _run_command_tts("fake tts", timeout=0.25)
|
||||
|
||||
assert result.returncode == 0
|
||||
assert result.stdout == "done"
|
||||
assert result.stderr == "tick"
|
||||
assert read_sizes["stdout"][0] == 65536
|
||||
assert read_sizes["stderr"][0] == 65536
|
||||
|
||||
def test_stderr_progress_extends_beyond_timeout(self, tmp_path):
|
||||
script = tmp_path / "progress_then_exit.py"
|
||||
script.write_text(
|
||||
|
|
@ -403,6 +436,7 @@ class TestRunCommandTts:
|
|||
)
|
||||
|
||||
assert "starting tier 1" in (excinfo.value.stderr or "")
|
||||
assert isinstance(excinfo.value.__cause__, subprocess.TimeoutExpired)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -1025,9 +1025,19 @@ def _run_command_tts(command: str, timeout: float) -> subprocess.CompletedProces
|
|||
open_streams = {"stdout", "stderr"}
|
||||
|
||||
def read_stream(name: str, stream: Any) -> None:
|
||||
encoding = getattr(stream, "encoding", None) or "utf-8"
|
||||
try:
|
||||
while True:
|
||||
chunk = stream.read(1)
|
||||
try:
|
||||
fd = stream.fileno()
|
||||
except (AttributeError, OSError):
|
||||
fd = None
|
||||
|
||||
if fd is None:
|
||||
chunk = stream.read(65536)
|
||||
else:
|
||||
data = os.read(fd, 65536)
|
||||
chunk = data.decode(encoding, errors="replace")
|
||||
if not chunk:
|
||||
break
|
||||
output_queue.put((name, chunk))
|
||||
|
|
@ -1079,12 +1089,15 @@ def _run_command_tts(command: str, timeout: float) -> subprocess.CompletedProces
|
|||
chunks[name].append(chunk)
|
||||
stdout = "".join(chunks["stdout"])
|
||||
stderr = "".join(chunks["stderr"])
|
||||
raise subprocess.TimeoutExpired(
|
||||
command,
|
||||
timeout,
|
||||
output=stdout,
|
||||
stderr=stderr,
|
||||
)
|
||||
try:
|
||||
raise subprocess.TimeoutExpired(command, timeout)
|
||||
except subprocess.TimeoutExpired as exc:
|
||||
raise subprocess.TimeoutExpired(
|
||||
command,
|
||||
timeout,
|
||||
output=stdout,
|
||||
stderr=stderr,
|
||||
) from exc
|
||||
|
||||
stdout = "".join(chunks["stdout"])
|
||||
stderr = "".join(chunks["stderr"])
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue