From b14741dca0ac6eeddf4b4561cff457ba552680bd Mon Sep 17 00:00:00 2001 From: vegu-ai-tools <152010387+vegu-ai-tools@users.noreply.github.com> Date: Sun, 29 Mar 2026 13:38:29 +0300 Subject: [PATCH] Enhance TTS agent functionality by adding a context manager to suppress automatic voice generation during multi-turn planning in DirectorChatMixin. This prevents noisy voice synthesis and improves user experience. Also, introduced a property to check if auto generation is enabled. --- src/talemate/agents/director/chat/mixin.py | 29 ++++++++++++++++------ src/talemate/agents/tts/__init__.py | 27 ++++++++++++++++++++ 2 files changed, 48 insertions(+), 8 deletions(-) diff --git a/src/talemate/agents/director/chat/mixin.py b/src/talemate/agents/director/chat/mixin.py index 5b25e7d9..7b4c22a5 100644 --- a/src/talemate/agents/director/chat/mixin.py +++ b/src/talemate/agents/director/chat/mixin.py @@ -1,7 +1,9 @@ import structlog from typing import Any, TYPE_CHECKING, Callable, Awaitable +import talemate.instance as instance from talemate.agents.base import set_processing, AgentAction, AgentActionConfig +from talemate.emit import emit from talemate.game.engine.nodes.core import GraphState from talemate.agents.director.action_core import utils as action_utils @@ -957,12 +959,23 @@ class DirectorChatMixin: """ Start arc generation. Like chat_generate_next but with @set_processing to ensure active_agent context is available. + + Suppresses automatic TTS generation while arcs are being generated to + avoid noisy voice synthesis during long multi-step planning. """ - return await self.chat_generate_next( - chat_id, - on_update=on_update, - on_done=on_done, - on_compacting=on_compacting, - on_compacted=on_compacted, - on_title_generated=on_title_generated, - ) + tts_agent = instance.get_agent("tts") + if tts_agent.enabled and tts_agent.has_auto_generation: + emit( + "status", + "Automatic voice generation is paused during multi-turn generation.", + status="info", + ) + with tts_agent.suppress_auto_generation(): + return await self.chat_generate_next( + chat_id, + on_update=on_update, + on_done=on_done, + on_compacting=on_compacting, + on_compacted=on_compacted, + on_title_generated=on_title_generated, + ) diff --git a/src/talemate/agents/tts/__init__.py b/src/talemate/agents/tts/__init__.py index 46bc929f..355051f4 100644 --- a/src/talemate/agents/tts/__init__.py +++ b/src/talemate/agents/tts/__init__.py @@ -2,6 +2,7 @@ from __future__ import annotations import asyncio import base64 +import contextlib import traceback import uuid from collections import deque @@ -226,6 +227,7 @@ class TTSAgent( self.is_enabled = False # tts agent is disabled by default self.actions = TTSAgent.init_actions() self.playback_done_event = asyncio.Event() + self._suppress_auto_generation: int = 0 # Queue management for voice generation # Each queue instance gets a unique id so it can later be referenced @@ -241,6 +243,19 @@ class TTSAgent( self._queue_task: asyncio.Task | None = None self._queue_lock = asyncio.Lock() + @contextlib.contextmanager + def suppress_auto_generation(self): + """Context manager to suppress automatic TTS generation. + + While active, reactive generation triggered by game_loop_new_message + is skipped. Explicit calls to generate() still work. + """ + self._suppress_auto_generation += 1 + try: + yield + finally: + self._suppress_auto_generation -= 1 + # general helpers @property @@ -283,6 +298,15 @@ class TTSAgent( self.actions["_config"].config["generate_for_context_investigation"].value ) + @property + def has_auto_generation(self) -> bool: + return any([ + self.generate_for_npc, + self.generate_for_player, + self.generate_for_narration, + self.generate_for_context_investigation, + ]) + @property def speaker_separation(self) -> str: return self.actions["_config"].config["speaker_separation"].value @@ -468,6 +492,9 @@ class TTSAgent( Called when a conversation is generated """ + if self._suppress_auto_generation: + return + if self.scene.environment == "creative": return