@@ -47,6 +47,7 @@ import { NoKeyOverlay } from './NoKeyOverlay';
4747import { useAutoAgentSelect } from './useAgentAutoSelect' ;
4848import { useOpenRouterModels } from './useOpenRouterModels' ;
4949import type { MentionItem } from '../../chunks/MarkdownEditor/AIChatInput/types' ;
50+ import { flushSync } from 'react-dom' ;
5051
5152const AIChatInput = React . lazy (
5253 ( ) => import ( '../../chunks/MarkdownEditor/AIChatInput/AsyncAIChatInput' ) ,
@@ -82,6 +83,7 @@ interface SimpleAIChatProps {
8283 React . SetStateAction < AIMessageContext [ ] >
8384 > ;
8485 onDeleteMessage : ( message : AIChatDisplayMessage ) => void ;
86+ onRegenerateMessage : ( message : AIChatDisplayMessage ) => Promise < void > ;
8587}
8688
8789export const SimpleAIChat : React . FC <
@@ -94,6 +96,7 @@ export const SimpleAIChat: React.FC<
9496 setExternalContextItems,
9597 onNewMessage,
9698 onDeleteMessage,
99+ onRegenerateMessage,
97100 children,
98101} ) => {
99102 const abortSignalRef = useRef < AbortController > ( null ) ;
@@ -140,11 +143,12 @@ export const SimpleAIChat: React.FC<
140143 const [ tokensUsed , setTokensUsed ] = useState < [ number , number ] > ( [ 0 , 0 ] ) ;
141144
142145 const getToolsForAgent = useTools ( ) ;
143- const [ hasToolResultFollowUp , setHasToolResultFollowUp ] = useState ( false ) ;
144146
145147 const [ agentConfigOpen , setAgentConfigOpen ] = useState ( false ) ;
146148 const pickAgent = useAutoAgentSelect ( ) ;
147149
150+ const [ shouldRegenMessages , setShouldRegenMessages ] = useState ( false ) ;
151+
148152 const normalizeAndApplyContext = useProcessMessages ( ) ;
149153
150154 const { tools : atomicTools } = useAtomicMCPTools ( {
@@ -225,7 +229,12 @@ export const SimpleAIChat: React.FC<
225229 setUserSelectedContextItems ( newContextItems ) ;
226230 } ;
227231
228- const sendMessage = async ( isFollowUp = false ) => {
232+ const sendMessage = async ( {
233+ regenerate = false ,
234+ } : {
235+ /** Whether to regenerate the response */
236+ regenerate ?: boolean ;
237+ } = { } ) => {
229238 if ( readonly ) {
230239 toast . error ( 'You do not have the permissions to edit this chat.' ) ;
231240
@@ -281,21 +290,28 @@ export const SimpleAIChat: React.FC<
281290 ...userSelectedContextItems ,
282291 ] ;
283292
284- if ( ! isFollowUp ) {
293+ if ( regenerate ) {
294+ messagesToUse = messages ;
295+ } else {
285296 const userMessage = prepareUserMessage (
286297 userInput ,
287298 attachedFile ,
288299 allContextItems ,
289300 ) ;
290301 messagesToUse = [ ...messages , userMessage ] ;
291302 onNewMessage ( userMessage ) ;
292- } else {
293- messagesToUse = messages ;
294303 }
295304
296305 // Filter message to only include non-error messages, error messages are only intended for the user.
297306 const filteredMessages = await normalizeAndApplyContext ( messagesToUse ) ;
298307
308+ console . log (
309+ 'last message sent as context: "' ,
310+ filteredMessages . at ( - 1 ) . content [ 0 ] . text ,
311+ 'other mgss' ,
312+ filteredMessages ,
313+ ) ;
314+
299315 // Update messages with the user message first
300316 setExternalContextItems ( [ ] ) ;
301317 setUserSelectedContextItems ( [ ] ) ;
@@ -545,13 +561,6 @@ export const SimpleAIChat: React.FC<
545561 }
546562 } ;
547563
548- useEffect ( ( ) => {
549- if ( hasToolResultFollowUp ) {
550- setHasToolResultFollowUp ( false ) ;
551- sendMessage ( true ) ;
552- }
553- } , [ hasToolResultFollowUp ] ) ;
554-
555564 // Combine both context item lists when needed
556565 const allContextItems = [
557566 ...externalContextItems ,
@@ -564,18 +573,37 @@ export const SimpleAIChat: React.FC<
564573 } ) ;
565574 } ;
566575
576+ const regenerateMessage = async ( message : AIChatDisplayMessage ) => {
577+ flushSync ( async ( ) => {
578+ // Removes the following messages
579+ await onRegenerateMessage ( message ) ;
580+
581+ setShouldRegenMessages ( true ) ;
582+ } ) ;
583+ } ;
584+
585+ useEffect ( ( ) => {
586+ if ( shouldRegenMessages ) {
587+ sendMessage ( {
588+ regenerate : true ,
589+ } ) ;
590+ setShouldRegenMessages ( false ) ;
591+ }
592+ } , [ shouldRegenMessages ] ) ;
593+
567594 return (
568595 < ChatWindow fullView = { fullView } >
569596 { children }
570597 < ChatMessagesContainer
571598 enableAutoScroll = { aiState !== AIState . Stopped }
572599 fullView = { fullView }
573600 >
574- { messages . filter ( cleanMessages ) . map ( message => (
601+ { messages . filter ( cleanMessages ) . map ( ( message , index ) => (
575602 < AIChatMessage
576- key = { JSON . stringify ( message ) }
603+ key = { ` ${ JSON . stringify ( message ) } - ${ index } ` }
577604 message = { message }
578605 onDeleteMessage = { onDeleteMessage }
606+ onRegenerateMessage = { regenerateMessage }
579607 />
580608 ) ) }
581609 { ongoingMessage . text && (
0 commit comments