blitztext-app-linux/linux/tests/test_llm_stream.py
mARTin-B78 ae01472b77 overlay: fix AT-SPI caret freeze; fuse routing match + live LLM into HUD; Release 1.6.0
Fix a desktop-session freeze (forced logout/reboot) caused by the overlay's
AT-SPI caret tracker: it subscribed to the high-frequency object:text-caret-moved
signal and made synchronous, blocking AT-SPI reads from inside the event handler,
re-entering the a11y dispatcher and getting stormed by the app's own xdotool
typing until GNOME stopped responding. Now track focus changes only and read the
caret rectangle lazily, once, when the overlay shows — never on the hot path.

Fuse voice-routing feedback into the overlay instead of a desktop notification:
show the matched preset's emoji, name, and spoken keyword on a banner, narrate
the phase (Transcribing -> Rewriting), and stream the LLM rewrite into the bubble
token-by-token. Redundant per-dictation notifications are suppressed when the
overlay is present (errors still notify); headless/overlay-off is unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 16:58:47 +02:00

42 lines
1.3 KiB
Python

"""Streaming the LLM rewrite into the overlay (so you watch the model write).
`llm.chat(..., on_token=cb)` must parse an OpenAI-style SSE stream, hand each
content delta to the callback, and still return the complete text.
"""
import io
import blitztext.llm as llm
def test_read_stream_accumulates_and_calls_back():
sse = (
'data: {"choices":[{"delta":{"content":"Hel"}}]}\n'
"\n" # keep-alive blank line
'data: {"choices":[{"delta":{"content":"lo"}}]}\n'
'data: {"choices":[{"delta":{}}]}\n' # role-only / empty delta
": comment line\n" # SSE comment, ignored
"data: [DONE]\n"
'data: {"choices":[{"delta":{"content":"X"}}]}\n' # after DONE -> ignored
)
tokens = []
out = llm._read_stream(io.BytesIO(sse.encode("utf-8")), tokens.append)
assert out == "Hello"
assert tokens == ["Hel", "lo"]
def test_read_stream_survives_callback_errors():
sse = (
'data: {"choices":[{"delta":{"content":"a"}}]}\n'
'data: {"choices":[{"delta":{"content":"b"}}]}\n'
"data: [DONE]\n"
)
def boom(_delta):
raise RuntimeError("UI exploded")
# A failing UI callback must not break accumulation / delivery.
out = llm._read_stream(io.BytesIO(sse.encode("utf-8")), boom)
assert out == "ab"