@@ -194,10 +194,18 @@ export function DashboardAgentPanel({
194194 // Bumped on each open so a slower earlier open can't overwrite a newer one.
195195 const openChatRequestSeq = useRef ( 0 ) ;
196196
197+ // Bound to its chat, which remounts with a fresh guard ref on every switch.
198+ const [ sendRequest , setSendRequest ] = useState <
199+ { text : string ; seq : number ; chatId : string } | undefined
200+ > ( undefined ) ;
201+
197202 // The one way the panel changes chat: it invalidates any in-flight open and abandons a
198203 // half-configured watch card, which would otherwise be submitted against the new chat.
199204 const claimChatSlot = useCallback ( ( ) => {
200205 dispatchWatchCard ( { type : "chat-changed" } ) ;
206+ // A request belongs to the chat it was made in: the remounting chat has a fresh guard ref,
207+ // so a kept request would be sent a second time.
208+ setSendRequest ( undefined ) ;
201209 return ++ openChatRequestSeq . current ;
202210 } , [ ] ) ;
203211
@@ -357,10 +365,6 @@ export function DashboardAgentPanel({
357365 onUnreadWorkChange ?.( unreadWorkCount ( chats , active ?. chatId ) ) ;
358366 } , [ chats , chatsLoaded , active ?. chatId , onUnreadWorkChange ] ) ;
359367
360- // Bound to its chat, which remounts with a fresh guard ref on every switch.
361- const [ sendRequest , setSendRequest ] = useState <
362- { text : string ; seq : number ; chatId : string } | undefined
363- > ( undefined ) ;
364368 const handledRequestSeq = useRef < number | undefined > ( undefined ) ;
365369 useEffect ( ( ) => {
366370 if ( ! requestedMessage || handledRequestSeq . current === requestedMessage . seq ) return ;
0 commit comments