mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-09-26 11:34:50 +02:00
[eric] chat: keep the user message on remount for any live session, not just still-pending ones (ws echo clears pending instantly)
This commit is contained in:
@@ -1227,27 +1227,33 @@ const agentsSlice = createSlice({
|
||||
.addCase(fetchSession.fulfilled, (state, action) => {
|
||||
const session = action.payload;
|
||||
const existing = state.sessions[session.id];
|
||||
// Preserve optimistic-pending messages the server snapshot doesn't carry
|
||||
// yet. On remount mid-stream (leave the chat + come back) this fetch's
|
||||
// snapshot predates the just-sent user turn, so a blind replace wiped the
|
||||
// user's own message bubble while the assistant stream (separate slice)
|
||||
// kept going. Carry forward any local pending message not already echoed
|
||||
// in the snapshot; the WS echo / next fetch dedupes it by client_message_id.
|
||||
// Preserve local messages the server snapshot doesn't carry yet. On
|
||||
// remount mid-stream (leave the chat + come back) this fetch's snapshot
|
||||
// predates the just-sent user turn, so a blind replace wiped the user's
|
||||
// own bubble while the assistant stream (separate slice) kept going.
|
||||
// The WS echo clears optimistic_status the instant it arrives, so the
|
||||
// message is usually "confirmed but not yet server-persisted" rather than
|
||||
// still 'pending' (that's why a pending-only filter missed it). Gate on
|
||||
// the session being LIVE: on a running/streaming session, carry forward
|
||||
// any local message the snapshot lacks; on a settled session the snapshot
|
||||
// is authoritative (so a server-side delete isn't resurrected).
|
||||
const incomingMsgs = session.messages ?? [];
|
||||
const liveStatus = session.status === 'running' || session.status === 'waiting_approval';
|
||||
const incomingClientIds = new Set(
|
||||
incomingMsgs.map((m) => m.client_message_id).filter(Boolean),
|
||||
);
|
||||
const incomingIds = new Set(incomingMsgs.map((m) => m.id));
|
||||
const survivingOptimistic = (existing?.messages ?? []).filter(
|
||||
(m) =>
|
||||
m.optimistic_status === 'pending' &&
|
||||
!(m.client_message_id && incomingClientIds.has(m.client_message_id)) &&
|
||||
!incomingIds.has(m.id),
|
||||
);
|
||||
const surviving = liveStatus
|
||||
? (existing?.messages ?? []).filter(
|
||||
(m) =>
|
||||
!incomingIds.has(m.id) &&
|
||||
!(m.client_message_id && incomingClientIds.has(m.client_message_id)),
|
||||
)
|
||||
: [];
|
||||
state.sessions[session.id] = {
|
||||
...session,
|
||||
messages: survivingOptimistic.length
|
||||
? [...incomingMsgs, ...survivingOptimistic]
|
||||
messages: surviving.length
|
||||
? [...incomingMsgs, ...surviving]
|
||||
: incomingMsgs,
|
||||
pending_approvals: session.pending_approvals ?? existing?.pending_approvals ?? [],
|
||||
tool_group_meta: session.tool_group_meta ?? existing?.tool_group_meta ?? {},
|
||||
|
||||
Reference in New Issue
Block a user