Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions packages/visual/src/agent_media_visual/canvas.py
Original file line number Diff line number Diff line change
Expand Up @@ -497,14 +497,22 @@ def _child_env() -> dict:
return env


# `media say` / replay block until the utterance finishes PLAYING (not merely
# rendering), so a per-turn play of a long assistant turn legitimately runs for
# minutes. This subprocess timeout is only a hung-process backstop, NOT a length
# limit — a low cap kills `media say` mid-sentence and cuts the audio off. Keep
# it well past any real turn; override via MEDIA_VISUAL_SAY_TIMEOUT if needed.
_SAY_TIMEOUT_S = int(os.environ.get("MEDIA_VISUAL_SAY_TIMEOUT") or 900)


def _say(text: str) -> bool:
"""Speak arbitrary text through the speech channel — per-turn 'play'."""
text = (text or "").strip()
if not text:
return False
try:
subprocess.run([_media_bin(), "say", text], env=_child_env(),
timeout=20, check=False)
timeout=_SAY_TIMEOUT_S, check=False)
return True
except (OSError, subprocess.SubprocessError):
return False
Expand All @@ -521,7 +529,7 @@ def _play_pane(pane: str) -> bool:
env = {**_child_env(), "TTS_POPUP_PANE": pane}
try:
subprocess.run([_media_bin(), "replay-at-cursor"], env=env,
timeout=10, check=False)
timeout=_SAY_TIMEOUT_S, check=False)
return True
except (OSError, subprocess.SubprocessError):
return False
Expand Down
Loading