修复新会话可能出现响应不显示的情况

This commit is contained in:
xintaofei
2026-03-11 13:06:05 +08:00
parent 7dabb74de3
commit f74fe371da
3 changed files with 16 additions and 3 deletions

View File

@@ -277,6 +277,11 @@ const ConversationTabView = memo(function ConversationTabView({
async (refreshConversationId: number) => { async (refreshConversationId: number) => {
try { try {
const refreshed = await refreshDetailCache(refreshConversationId) const refreshed = await refreshDetailCache(refreshConversationId)
// Skip ACK during prompting to avoid clearing liveMessage /
// resetting syncState while streaming. The useEffect with the
// connStatus === "prompting" guard will handle it naturally
// once prompting ends.
if (prevStatusRef.current === "prompting") return
acknowledgePersistedDetail(refreshConversationId, refreshed) acknowledgePersistedDetail(refreshConversationId, refreshed)
} catch (error) { } catch (error) {
setSyncState(refreshConversationId, "failed") setSyncState(refreshConversationId, "failed")

View File

@@ -165,6 +165,8 @@ export function MessageListView({
[sharedT] [sharedT]
) )
const sessionSyncState = session?.syncState ?? "idle"
const { threadItems, nonStreamingAdapted } = useMemo(() => { const { threadItems, nonStreamingAdapted } = useMemo(() => {
const allTurns = timelineTurns.map((item) => item.turn) const allTurns = timelineTurns.map((item) => item.turn)
const allAdapted = adaptMessageTurns(allTurns, adapterText) const allAdapted = adaptMessageTurns(allTurns, adapterText)
@@ -206,12 +208,15 @@ export function MessageListView({
} }
const lastPhase = timelineTurns[timelineTurns.length - 1]?.phase ?? null const lastPhase = timelineTurns[timelineTurns.length - 1]?.phase ?? null
if (connStatus === "prompting" && lastPhase === "optimistic") { if (
lastPhase === "optimistic" &&
(connStatus === "prompting" || sessionSyncState === "awaiting_persist")
) {
items.push({ key: "pending-typing", kind: "typing" }) items.push({ key: "pending-typing", kind: "typing" })
} }
return { threadItems: items, nonStreamingAdapted: nonStreaming } return { threadItems: items, nonStreamingAdapted: nonStreaming }
}, [adapterText, connStatus, timelineTurns]) }, [adapterText, connStatus, sessionSyncState, timelineTurns])
const historicalPlanEntries = useMemo( const historicalPlanEntries = useMemo(
() => extractLatestPlanEntriesFromMessages(nonStreamingAdapted), () => extractLatestPlanEntriesFromMessages(nonStreamingAdapted),

View File

@@ -250,7 +250,10 @@ function reduceHydrateDetail(
...(current ?? createEmptySession(conversationId)), ...(current ?? createEmptySession(conversationId)),
externalId: nextExternalId, externalId: nextExternalId,
persistedTurns, persistedTurns,
liveMessage: hasPersistedAdvance ? null : (current?.liveMessage ?? null), liveMessage:
hasPersistedAdvance && current?.syncState !== "awaiting_persist"
? null
: (current?.liveMessage ?? null),
optimisticTurns: shouldDropOptimistic ? [] : optimisticTurns, optimisticTurns: shouldDropOptimistic ? [] : optimisticTurns,
syncState: shouldDropOptimistic ? "idle" : (current?.syncState ?? "idle"), syncState: shouldDropOptimistic ? "idle" : (current?.syncState ?? "idle"),
activeTurnToken: shouldDropOptimistic activeTurnToken: shouldDropOptimistic