From 5de0df631d0135701e352e93c8c14343118d2a09 Mon Sep 17 00:00:00 2001 From: miro Date: Fri, 30 Jan 2026 13:17:46 +0000 Subject: [PATCH 1/2] fix: explicitly model streaming tokens vs sentences --- ovos_plugin_manager/templates/agents.py | 40 ++++++++++++++++++++--- ovos_plugin_manager/thirdparty/solvers.py | 2 +- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/ovos_plugin_manager/templates/agents.py b/ovos_plugin_manager/templates/agents.py index 0f763545..f0204026 100644 --- a/ovos_plugin_manager/templates/agents.py +++ b/ovos_plugin_manager/templates/agents.py @@ -225,12 +225,16 @@ def continue_chat(self, messages: List[AgentMessage], """ raise NotImplementedError() - def stream_chat(self, messages: List[AgentMessage], + def stream_tokens(self, messages: List[AgentMessage], session_id: str = "default", lang: Optional[str] = None, - units: Optional[str] = None) -> Iterable[AgentMessage]: + units: Optional[str] = None) -> Iterable[str]: """ - Stream back response messages as they are generated. + Stream back response tokens as they are generated. + + Returns partial sentences and is not suitable for direct TTS. + + Once merged the output corresponds to the content of a AgentMessage with MessageRole.ASSISTANT Note: Default implementation yields the full response from continue_chat. @@ -243,9 +247,35 @@ def stream_chat(self, messages: List[AgentMessage], units (str, optional): Unit system. Returns: - Iterable[AgentMessage]: A stream of response messages. + Iterable[str]: A stream of tokens/partial text. """ - yield self.continue_chat(messages, session_id, lang, units) + yield from self.continue_chat(messages, session_id, lang, units).content.split() + + def stream_sentences(self, messages: List[AgentMessage], + session_id: str = "default", + lang: Optional[str] = None, + units: Optional[str] = None) -> Iterable[str]: + """ + Stream back response sentences as they are generated. + + Returns full sentences only, suitable for direct TTS. + + Once merged the output corresponds to the content of a AgentMessage with MessageRole.ASSISTANT + + Note: + Default implementation yields the full response from continue_chat. + Subclasses should override this for real-time token streaming. + + Args: + messages (List[AgentMessage]): Full list of messages. + session_id (str): Identifier for the session. + lang (str, optional): Language code. + units (str, optional): Unit system. + + Returns: + Iterable[str]: A stream of tokens/partial text. + """ + yield from self.continue_chat(messages, session_id, lang, units).content.split("\n") def get_response(self, utterance: str, session_id: str = "default", diff --git a/ovos_plugin_manager/thirdparty/solvers.py b/ovos_plugin_manager/thirdparty/solvers.py index db20a78b..7556b796 100644 --- a/ovos_plugin_manager/thirdparty/solvers.py +++ b/ovos_plugin_manager/thirdparty/solvers.py @@ -107,7 +107,7 @@ def sentence_split(text: str, max_sentences: int = 25) -> List[str]: for t in text.split("\n")])[:max_sentences] except Exception as e: LOG.exception(f"Error in sentence_split: {e}") - return [text] + return text.split("\n") @lru_cache(maxsize=128) def detect_language(self, text: str) -> str: From 2c8f267ec43b84b6d408cf578412485faef3bedc Mon Sep 17 00:00:00 2001 From: JarbasAI <33701864+JarbasAl@users.noreply.github.com> Date: Fri, 30 Jan 2026 14:12:45 +0000 Subject: [PATCH 2/2] Apply suggestion from @coderabbitai[bot] Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- ovos_plugin_manager/templates/agents.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ovos_plugin_manager/templates/agents.py b/ovos_plugin_manager/templates/agents.py index f0204026..59d2908c 100644 --- a/ovos_plugin_manager/templates/agents.py +++ b/ovos_plugin_manager/templates/agents.py @@ -264,7 +264,7 @@ def stream_sentences(self, messages: List[AgentMessage], Note: Default implementation yields the full response from continue_chat. - Subclasses should override this for real-time token streaming. + Subclasses should override this for real-time sentence streaming. Args: messages (List[AgentMessage]): Full list of messages. @@ -273,7 +273,7 @@ def stream_sentences(self, messages: List[AgentMessage], units (str, optional): Unit system. Returns: - Iterable[str]: A stream of tokens/partial text. + Iterable[str]: A stream of complete sentences. """ yield from self.continue_chat(messages, session_id, lang, units).content.split("\n")