From a5b82726be3e218c6b37b0b5612329d160c97abc Mon Sep 17 00:00:00 2001 From: charan Date: Fri, 21 Aug 2026 03:21:58 +0530 Subject: [PATCH] Fix browser SyntaxError on the SSE [DONE] sentinel The stream ends with `data: [DONE]`, which is not JSON. The page fed every data line to JSON.parse, so the sentinel threw "Unexpected token 'D'" and the caught error was painted red under an otherwise complete answer. Skip the [DONE] line (and any empty data line) before parsing. --- rag/bin/rag-web.py | 3 ++- tests/test_web.py | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/rag/bin/rag-web.py b/rag/bin/rag-web.py index 8635fde..1059125 100644 --- a/rag/bin/rag-web.py +++ b/rag/bin/rag-web.py @@ -137,7 +137,8 @@ const parts=buf.split('\\n\\n'); buf=parts.pop(); for(const p of parts){ const line=p.split('\\n').find(l=>l.startsWith('data:')); if(!line) continue; - const ev=JSON.parse(line.slice(5)); + const data=line.slice(5).trim(); if(!data||data==='[DONE]') continue; + const ev=JSON.parse(data); if(ev.token){text+=ev.token; body.innerHTML=render(text); ad.scrollIntoView({block:'end'})} if(ev.error){body.innerHTML+='
'+esc(ev.error)+'
'} diff --git a/tests/test_web.py b/tests/test_web.py index e362cea..a1d8497 100644 --- a/tests/test_web.py +++ b/tests/test_web.py @@ -95,6 +95,12 @@ def test_page_asks_for_a_key_and_sends_it(web): assert "res.status===401" in body +def test_page_skips_the_done_sentinel(web): + """The [DONE] line is not JSON; the page must skip it, not parse it.""" + body = get(web.url + "/").read().decode() + assert "data==='[DONE]'" in body + + def test_models_endpoint_names_the_rag_model(web): body = json.load(get(web.url + "/v1/models")) assert body["data"][0]["id"] == "cpts-notes-rag"