The fetch-based reader makes the POST body and authorization header practical. One detail in its parsing loop deserves a stronger failure path: ignoring a JSON parse error can discard a chunk while a later done event still makes the response look complete.
I would distinguish a clean application-level done event from transport EOF, and mark malformed events as a stream failure instead of silently continuing. A byte-fragmentation fixture could split a response at every possible boundary, including inside a multibyte character, and require identical reconstructed output. A second fixture ending before done would check that truncated answers cannot appear as successful completions.
Thank you for this - you are completely right on both points.
I went back and checked the code directly after reading your comment:
The catch {} block in the parsing loop silently swallows any malformed frame. If a chunk fails JSON.parse() and a done event arrives later, the response appears complete to the user even if words were dropped mid-sentence.
The loop breaks on transport EOF (reader.read() returning { done: true }) without verifying that an application-level {"type": "done"} event was actually received. A dropped Wi-Fi connection or an NGINX idle timeout would silently leave a truncated answer on screen with no warning to the user.
Both are genuine gaps in the failure path. Since IntelliDesk AI is still actively in development, I am patching both in the next push - adding a receivedDone flag to distinguish clean completion from transport disconnect, and surfacing parse failures explicitly rather than ignoring them.
The byte-fragmentation fixture idea is also excellent. I want to add a test that splits a mock SSE response at every byte boundary, including inside multi-byte UTF-8 characters, and asserts identical reconstructed output. That kind of fixture would catch regressions immediately if the buffer logic ever changes.
Really appreciate you reading the implementation this carefully and taking the time to write this up.
The receivedDone flag gives the UI a concrete distinction between a completed answer and an interrupted one. I would preserve the partial text on failure while marking it incomplete, rather than clearing useful output or presenting it as a normal response.
For the fragmentation fixture, make sure the decoder retains UTF-8 state across reads and is flushed at EOF. An unfinished final code point or an unterminated event should exercise the failure path too. That checks both the byte decoder and the event parser around the boundary your patch is tightening.
The partial text was already being saved on failure, but I just patched the other edge cases you called out. Added the decoder.decode() flush at the end for split characters, and set up a check on the trailing buffer so cut-off frames and missing done events actually trigger the interrupted/retry state instead of silently failing.
Super helpful feedback, thanks for taking the time to write it down!
Ahmet Özel
AI Engineer. Computer Vision, RAG and LLM agents.
The fetch-based reader makes the POST body and authorization header practical. One detail in its parsing loop deserves a stronger failure path: ignoring a JSON parse error can discard a chunk while a later done event still makes the response look complete.
I would distinguish a clean application-level done event from transport EOF, and mark malformed events as a stream failure instead of silently continuing. A byte-fragmentation fixture could split a response at every possible boundary, including inside a multibyte character, and require identical reconstructed output. A second fixture ending before done would check that truncated answers cannot appear as successful completions.