fix: clear stale busy state before send

This commit is contained in:
ai-ag2026
2026-05-23 11:34:18 +02:00
parent dcee0563c1
commit 3a73400da3
2 changed files with 42 additions and 0 deletions
+27
View File
@@ -190,6 +190,32 @@ let _sendInProgress = false;
let _sendInProgressSid = null; // session_id of the in-flight send
const _sessionTitleProvisionalBySid = new Map();
function _clearStaleBusyStateBeforeSend({compressionRunning=false}={}){
if(!S||!S.busy||compressionRunning) return false;
const session=S.session||{};
const sid=session.session_id||'';
const hasRuntimeConfirmation=Boolean(
S.activeStreamId||
session.active_stream_id||
session.pending_user_message||
session.pending_started_at
);
if(hasRuntimeConfirmation) return false;
if(typeof INFLIGHT==='object'&&INFLIGHT&&sid&&INFLIGHT[sid]){
delete INFLIGHT[sid];
if(typeof clearInflightState==='function') clearInflightState(sid);
}
S.activeStreamId=null;
if(session) session.active_stream_id=null;
if(typeof setBusy==='function') setBusy(false);
else S.busy=false;
if(typeof setComposerStatus==='function') setComposerStatus('');
if(typeof setStatus==='function') setStatus('');
if(typeof updateSendBtn==='function') updateSendBtn();
if(sid&&typeof clearOptimisticSessionStreaming==='function') clearOptimisticSessionStreaming(sid);
return true;
}
function _sessionTitleLooksDefaultOrProvisional(titleText, provisionalText){
const title=String(titleText||'').replace(/\s+/g,' ').trim();
if(!title||title==='Untitled'||title==='New Chat')return true;
@@ -262,6 +288,7 @@ async function send(){
}
const compressionRunning=typeof isCompressionUiRunning==='function'&&isCompressionUiRunning();
_clearStaleBusyStateBeforeSend({compressionRunning});
// If busy or a manual compression is still running, handle based on busy_input_mode
if(S.busy||compressionRunning){
if(text){
+15
View File
@@ -51,6 +51,21 @@ def test_stale_inflight_purge_preserves_current_send_before_stream_id_exists():
assert skip_idx < delete_idx, "the current-send skip must run before any purge deletion"
def test_send_clears_stale_busy_state_before_queue_branch():
"""A stale client-only busy flag must not divert a new user turn into the invisible queue."""
body = _function_body(MESSAGES_JS, "send")
assert "_clearStaleBusyStateBeforeSend" in body, (
"send() should reconcile client-only stale busy state before deciding busy/queue mode"
)
reconcile_idx = body.index("_clearStaleBusyStateBeforeSend")
busy_branch_idx = body.index("if(S.busy||compressionRunning)")
chat_start_idx = body.index("api('/api/chat/start'")
assert reconcile_idx < busy_branch_idx < chat_start_idx, (
"stale busy reconciliation must run before the queue branch and before /api/chat/start"
)
def test_server_absent_optimistic_first_turn_rows_are_not_kept_forever():
"""A local first-turn sidebar row must expire when /api/chat/start never persisted it."""
body = _function_body(SESSIONS_JS, "_mergeOptimisticFirstTurnSessions")