Skip to content

Commit a44ba21

Browse files
bzqzhengclaude
andcommitted
fix: prevent tool-pair summarization from being silently undone (#7413)
Two changes that fix a conversation state desync between server and UI: 1. Emit HistoryReplaced at end of agent loop iterations where conversation was mutated, so the UI stays in sync with server-side metadata changes (e.g. tool-pair summarization marking messages agent-invisible). 2. Stop sending conversation_so_far on normal chat turns. The server already has the authoritative conversation in its DB. Sending it back from the UI created a window where stale client state could overwrite server-side changes. Edit-in-place flow (onMessageUpdate) is unchanged. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 717d17a commit a44ba21

2 files changed

Lines changed: 10 additions & 1 deletion

File tree

crates/goose/src/agents/agent.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1617,10 +1617,20 @@ impl Agent {
16171617
}
16181618
}
16191619

1620+
let conversation_mutated = !messages_to_add.is_empty();
16201621
for msg in &messages_to_add {
16211622
session_manager.add_message(&session_config.id, msg).await?;
16221623
}
16231624
conversation.extend(messages_to_add);
1625+
1626+
// Notify the UI of conversation changes so its local state stays
1627+
// in sync with the server. Without this, the client may send back
1628+
// stale conversation_so_far on the next turn, overwriting server-side
1629+
// metadata mutations (e.g. from tool-pair summarization).
1630+
if conversation_mutated && !did_recovery_compact_this_iteration {
1631+
yield AgentEvent::HistoryReplaced(conversation.clone());
1632+
}
1633+
16241634
if exit_chat {
16251635
break;
16261636
}

ui/desktop/src/hooks/useChatStream.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -590,7 +590,6 @@ export function useChatStream({
590590
body: {
591591
session_id: sessionId,
592592
user_message: newMessage,
593-
...(hasExistingMessages && { conversation_so_far: currentState.messages }),
594593
},
595594
throwOnError: true,
596595
signal: abortControllerRef.current.signal,

0 commit comments

Comments
 (0)