From 811a40f2cc88c0a8b136093a78bbdf8fbe355e72 Mon Sep 17 00:00:00 2001 From: Adolfo Reyna Date: Wed, 12 Aug 2026 10:38:23 -0400 Subject: [PATCH] fix: isolate reasoning chunks from assistant spoken reply history and Web UI final reply --- hermes_llm.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/hermes_llm.py b/hermes_llm.py index 896c3bf..f0cb581 100644 --- a/hermes_llm.py +++ b/hermes_llm.py @@ -451,6 +451,7 @@ class HermesLLM(FrameProcessor): if not suppress_output: await self.push_frame(LLMFullResponseStartFrame()) chunks: list[str] = [] + spoken_chunks: list[str] = [] if self._keep_open: await self._ensure_persistent_proc() @@ -470,9 +471,9 @@ class HermesLLM(FrameProcessor): pass if server_ok or self._use_server: - await self._run_turn_server(utterance, chunks) + await self._run_turn_server(utterance, chunks, spoken_chunks) else: - await self._run_turn_cli(utterance, chunks) + await self._run_turn_cli(utterance, chunks, spoken_chunks) t1 = time.perf_counter() total_ms = int((t1 - t0) * 1000) @@ -491,7 +492,7 @@ class HermesLLM(FrameProcessor): except Exception: pass - full_reply = _clean_spoken_text(" ".join(chunks)) + full_reply = _clean_spoken_text(" ".join(spoken_chunks)) if 'spoken_chunks' in locals() and spoken_chunks else _clean_spoken_text(" ".join(chunks)) if full_reply: self._history.append({"role": "assistant", "content": full_reply}) logger.info(f"Hermes LLM ({self._model or 'default'}): {full_reply}") @@ -504,8 +505,10 @@ class HermesLLM(FrameProcessor): if self._on_reply: self._on_reply(full_reply) - async def _run_turn_server(self, utterance: str, chunks: list[str]): + async def _run_turn_server(self, utterance: str, chunks: list[str], spoken_chunks: list[str] | None = None): """Run turn via Hermes OpenAI-compatible Gateway API using SSE streaming (stream: true).""" + if spoken_chunks is None: + spoken_chunks = chunks try: ok, _ = await check_hermes_server_active(self._port) if not ok: @@ -616,6 +619,7 @@ class HermesLLM(FrameProcessor): if not cleaned_sent.endswith((".", "!", "?")): cleaned_sent += "." chunks.append(cleaned_sent) + spoken_chunks.append(cleaned_sent) await self.push_frame(LLMTextFrame(cleaned_sent)) try: import web_server @@ -639,6 +643,7 @@ class HermesLLM(FrameProcessor): if not cleaned_rem.endswith((".", "!", "?")): cleaned_rem += "." chunks.append(cleaned_rem) + spoken_chunks.append(cleaned_rem) await self.push_frame(LLMTextFrame(cleaned_rem)) try: import web_server @@ -666,8 +671,10 @@ class HermesLLM(FrameProcessor): pass await self._run_turn_cli(utterance, chunks) - async def _run_turn_cli(self, utterance: str, chunks: list[str]): + async def _run_turn_cli(self, utterance: str, chunks: list[str], spoken_chunks: list[str] | None = None): """Run turn via Hermes CLI using persistent session tracking.""" + if spoken_chunks is None: + spoken_chunks = chunks cmd = [self._cli_path, "chat", "-q", utterance, "-Q", "--source", "voice", "--reasoning", "none"] if self._session_id: cmd.extend(["-r", self._session_id]) @@ -735,6 +742,7 @@ class HermesLLM(FrameProcessor): cleaned = _clean_spoken_text(text_line) if cleaned: chunks.append(cleaned) + spoken_chunks.append(cleaned) await self.push_frame(LLMTextFrame(cleaned)) try: import web_server