Bladeren bron

Fixed counter/buffer mismatch

Efren Yevale Varela 1 maand geleden
bovenliggende
commit
838836880c
4 gewijzigde bestanden met toevoegingen van 51 en 3 verwijderingen
  1. 7 3
      src/stt_daemon/tui/app.py
  2. 2 0
      src/stt_daemon/tui/state.py
  3. 33 0
      tests/test_tui_app.py
  4. 9 0
      tests/test_tui_state.py

+ 7 - 3
src/stt_daemon/tui/app.py

@@ -159,9 +159,13 @@ class AssistantTUI(App):
 
         transcript_log = self.query_one("#transcript", RichLog)
         lines = state.transcript_lines()
-        while self._seen_transcripts < len(lines):
-            transcript_log.write(lines[self._seen_transcripts])
-            self._seen_transcripts += 1
+        new = state.transcripts_total - self._seen_transcripts
+        if new > 0:
+            # The state buffer is capped, so the running log can only append the
+            # lines still retained; `new` keeps counting past the cap.
+            for line in lines[max(0, len(lines) - new):]:
+                transcript_log.write(line)
+            self._seen_transcripts = state.transcripts_total
 
         lower_log = self.query_one("#chat", RichLog)
         if self._seen_epoch != state.chat_epoch:

+ 2 - 0
src/stt_daemon/tui/state.py

@@ -54,6 +54,7 @@ class ViewState:
     command_edited: bool = False
     in_flight: bool = False
     transcripts: list[dict] = field(default_factory=list)
+    transcripts_total: int = 0
     chat: list[dict] = field(default_factory=list)
     lower: list[tuple[str, bool]] = field(default_factory=list)
     tool: dict | None = None
@@ -126,6 +127,7 @@ class ViewState:
         elif etype == "transcript":
             self.transcripts.append(event)
             del self.transcripts[:-MAX_TRANSCRIPTS]
+            self.transcripts_total += 1
         elif etype == "chat_message":
             self.chat.append(event)
             del self.chat[:-MAX_CHAT]

+ 33 - 0
tests/test_tui_app.py

@@ -1589,3 +1589,36 @@ def test_maximize_restore_with_chat_content_keeps_chat_visible(server):
     assert observed["maximized"] is None
     assert observed["triage_display"] is True
     assert observed["chat_display"] is True
+
+
+def test_transcript_pane_keeps_updating_past_cap(server):
+    """Regression: past MAX_TRANSCRIPTS the running log must still append."""
+    pytest.importorskip("textual")
+    from textual.widgets import RichLog
+
+    from stt_daemon.tui.app import AssistantTUI
+    from stt_daemon.tui.state import MAX_TRANSCRIPTS
+
+    path, _service = server
+    app = AssistantTUI(path)
+    observed: dict = {}
+
+    async def scenario():
+        async with app.run_test(size=(80, 40)) as pilot:
+            await pilot.pause()
+            app._timer.stop()  # no background drain: server status must not clobber state
+            app._drain()
+            for i in range(MAX_TRANSCRIPTS + 5):
+                app.state.ingest({"type": "transcript", "text": f"t{i}", "lang": "en"})
+            app._render()
+            await pilot.pause()
+
+            app.state.ingest({"type": "transcript", "text": "after cap", "lang": "en"})
+            app._render()
+            await pilot.pause()
+            log = app.query_one("#transcript", RichLog)
+            observed["lines"] = [str(line) for line in log.lines]
+
+    asyncio.run(scenario())
+    assert any("after cap" in line for line in observed["lines"])
+    assert len(observed["lines"]) > MAX_TRANSCRIPTS

+ 9 - 0
tests/test_tui_state.py

@@ -117,6 +117,15 @@ def test_transcripts_are_bounded():
     assert state.transcript_lines()[-1].startswith("[en]")
 
 
+def test_transcripts_total_keeps_counting_past_the_cap():
+    """The bounded buffer drops old lines; the total must still advance."""
+    state = ViewState()
+    for i in range(MAX_TRANSCRIPTS + 25):
+        state.ingest({"type": "transcript", "text": f"t{i}", "lang": "en"})
+
+    assert state.transcripts_total == MAX_TRANSCRIPTS + 25
+
+
 def test_command_output_is_collected_for_display():
     state = ViewState()
     state.ingest({"type": "tool_call", "tool": "get_datetime", "args": {}})