fix(streaming): finish auto-compression card after rotation

This commit is contained in:
starship-s
2026-05-19 14:35:11 -06:00
parent 0310fcc466
commit 692ea22f9e
2 changed files with 29 additions and 10 deletions
+6 -3
View File
@@ -1829,12 +1829,15 @@ function attachLiveStream(activeSid, streamId, uploaded=[], options={}){
// Context was auto-compressed during this turn. Render it through the
// same transient compression-card path as manual /compress, without
// inserting a fake assistant message into history or model context.
if(!S.session||S.session.session_id!==activeSid) return;
if(!S.session) return;
const currentSid=S.session.session_id;
let d={};
try{ d=JSON.parse(e.data||'{}')||{}; }catch(_){ d={}; }
const eventSid=d.old_session_id||d.session_id||activeSid;
if(eventSid!==activeSid && d.new_session_id!==activeSid && d.continuation_session_id!==activeSid) return;
const continuationSid=d.new_session_id||d.continuation_session_id||'';
const eventMatchesCurrent=!!(currentSid&&(eventSid===currentSid||d.new_session_id===currentSid||d.continuation_session_id===currentSid));
if(!eventMatchesCurrent) return;
const displaySid=currentSid;
const message=String(d.message||'Context auto-compressed to continue the conversation').trim();
if(d.usage&&typeof _syncCtxIndicator==='function'){
S.lastUsage={...(S.lastUsage||{}),...d.usage};
@@ -1842,7 +1845,7 @@ function attachLiveStream(activeSid, streamId, uploaded=[], options={}){
}
if(typeof setCompressionUi==='function'){
const state={
sessionId:activeSid,
sessionId:displaySid,
phase:'done',
automatic:true,
message,
+23 -7
View File
@@ -217,16 +217,15 @@ def test_auto_compression_sse_uses_transient_card_not_fake_message():
def test_auto_compression_sse_keeps_inactive_and_malformed_paths_safe():
block = _compressed_listener_block()
guard = "if(!S.session||S.session.session_id!==activeSid) return;"
guard = "if(!S.session) return;"
assert guard in block
assert block.index(guard) < block.index("setCompressionUi")
assert "try{ d=JSON.parse(e.data||'{}')||{}; }catch(_){ d={}; }" in block
assert "const eventSid=d.old_session_id||d.session_id||activeSid;" in block
# The listener also accepts a rotated continuation session id so journal-
# replay reconnects after compression rotate land the done card.
# See Opus advisor followup on stage-385 (v0.51.92).
event_guard = "if(eventSid!==activeSid && d.new_session_id!==activeSid && d.continuation_session_id!==activeSid) return;"
assert "const eventMatchesCurrent=" in block
event_guard = "if(!eventMatchesCurrent) return;"
assert event_guard in block
assert block.index("const eventMatchesCurrent=") < block.index(event_guard)
def test_auto_compression_done_accepts_rotated_continuation_session_event():
@@ -238,12 +237,29 @@ def test_auto_compression_done_accepts_rotated_continuation_session_event():
# continuation id as display metadata instead of dropping the event.
assert "const eventSid=d.old_session_id||d.session_id||activeSid;" in block
assert "const continuationSid=d.new_session_id||d.continuation_session_id||'';" in block
event_guard = "if(eventSid!==activeSid && d.new_session_id!==activeSid && d.continuation_session_id!==activeSid) return;"
event_guard = "if(!eventMatchesCurrent) return;"
assert event_guard in block
assert block.index("const eventSid=") < block.index(event_guard)
assert block.index("const eventSid=") < block.index("const eventMatchesCurrent=")
assert "continuationSessionId:continuationSid" in block
def test_auto_compression_done_accepts_event_after_current_session_rotates():
block = _compressed_listener_block()
# The final compressed event can arrive/replay after another event has already
# updated S.session to the continuation session id. Do not drop it just
# because the active browser session no longer equals the original activeSid.
strict_active_guard = "if(!S.session||S.session.session_id!==activeSid) return;"
assert strict_active_guard not in block
assert "if(!S.session) return;" in block
assert "const currentSid=S.session.session_id;" in block
assert "const eventMatchesCurrent=" in block
assert "const displaySid=currentSid;" in block
assert "sessionId:displaySid" in block
assert block.index("const eventSid=") < block.index("const eventMatchesCurrent=")
assert block.index("const displaySid=") < block.index("setCompressionUi(state)")
def test_auto_compression_done_sse_refreshes_context_indicator_usage():
block = _compressed_listener_block()