mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-07-08 14:52:42 +08:00
fix(chat): make message queuing reliable across sessions and turn boundaries
Queued messages had four related defects: - A queued message flashed and then vanished at flush time: concurrent transcript refreshes (the `complete` handler racing the watcher-triggered update) could resolve out of order, letting a stale response overwrite newer server messages after the optimistic row was pruned. Session slots now carry a monotonic fetch ticket and discard stale fetch/refresh/ fetchMore responses. - Switching sessions flushed the previous session's queued draft into the newly viewed one (sending it with the wrong provider's settings, e.g. a Claude model into a Codex session). The composer flush is now scoped to its session, and a draft restored into an idle session sends after a short grace period so a live-run ack can cancel it. - The thinking banner never appeared for a queued turn: the chat handler's session-keyed completeRun safety net could fire after a queued message had already started the session's next run, emitting a spurious `complete` that killed it. The safety net is now scoped to its own run via completeRunIfCurrent (with a regression test). - Queued messages only sent while their session was being viewed. Drafts now persist their send options (model, effort, permissions) at queue time, and a new app-level useQueuedMessageAutoSend hook dispatches a non-viewed session's queued message as soon as its run completes, using the storage key as the claim ticket to prevent double sends.
This commit is contained in:
@@ -212,8 +212,10 @@ async function handleChatSend(
|
||||
} finally {
|
||||
// Safety net: a runtime that crashed (or resolved) without emitting its
|
||||
// terminal `complete` would otherwise leave the session stuck in
|
||||
// "processing" forever on every connected client.
|
||||
chatRunRegistry.completeRun(sessionId, { exitCode: 1 });
|
||||
// "processing" forever on every connected client. Scoped to THIS run —
|
||||
// a queued message can start the session's next run before this promise
|
||||
// settles, and the session-keyed completeRun would kill that new run.
|
||||
chatRunRegistry.completeRunIfCurrent(run, { exitCode: 1 });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user