fix(desktop): treat draining assistant text as settled for live-only chrome - #507
Merged
Astro-Han merged 3 commits intoJul 4, 2026
Merged
Conversation
…chrome Distinguish the streaming 'streaming' phase from the 'draining' phase so final assistant text smoothing through the smoother no longer keeps session event health polling alive, drives the sidebar pulse, disables the composer, or blocks permission mode transitions. - Introduce activeStreamingLive (phase === 'streaming') in app-shell.tsx and use it for composer streaming flag, permission mode disabled reason, and sidebar streamingSessionIds. - Switch useSessionEventHealthPolling to depend on activeStreamingLive instead of activeStreaming.length, so draining text does not hold the event stream health checker open. - Remove deferMessageRefresh in the 'complete' session event handler so committed history is always refreshed even while final text drains. - Add an effect that settles the draining slot once the committed assistant message arrives in messages, without requiring a session switch. - Add readMessagesWithSettleRetry with [120, 360]ms delays to tolerate read-model settle races during refreshMessages. - Update session-event-health, session-message-lifecycle-contract, session-status-presentation, and streaming-handoff contract tests to lock in the new behavior.
sunheyi6
force-pushed
the
fix/distinguish-streaming-draining-phase
branch
from
July 4, 2026 10:53
9833b8c to
5fada48
Compare
Astro-Han
approved these changes
Jul 4, 2026
Contributor
There was a problem hiding this comment.
LGTM. I pushed a small follow-up for the remaining non-blocking comments before merge:
- added a behavior test for complete firing before the committed assistant message is readable
- scoped the settle retry to complete/draining refreshes that can require the committed assistant message id; ordinary refreshes stay single-read
- kept the draining slot until that committed assistant message is readable
Verified:
- npm --workspace @maka/desktop run typecheck
- npm --workspace @maka/desktop test
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
背景
当前会话在 assistant 文本进入 draining 阶段(最终文本正在经 smoother 平滑写入历史)时,仍被当作"活跃流式输出"处理,导致:
complete事件中 deferMessageRefresh 会跳过已提交历史的刷新,draining 期间看不到完整消息。改动
将"活跃流式"的判定从
activeStreaming.length > 0收紧为activeStreamingLive(phase === 'streaming'才算活跃),让 draining 阶段视为已 settled:activeStreamingLive,用于 Composerstreaming、权限模式禁用原因、侧栏streamingSessionIds。messages,主动调用settleAssistantStreaming清掉 draining slot,无需切换会话。deferMessageRefresh,complete始终刷新refreshMessages。useSessionEventHealthPolling依赖activeStreamingLive而非activeStreaming.length。readMessagesWithSettleRetry([120, 360]ms重试)缓解读模型 settle 竞态,refreshMessages走该 helper。自测
风险