@@ -550,49 +550,66 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
550550 */
551551 const handleSendMessage = useCallback (
552552 ( text : string , images : string [ ] , fromQueue = false ) => {
553- text = text . trim ( )
554-
555- if ( text || images . length > 0 ) {
556- if ( sendingDisabled && ! fromQueue ) {
557- setMessageQueue ( ( prev ) => [ ...prev , { id : Date . now ( ) . toString ( ) , text, images } ] )
558- setInputValue ( "" )
559- setSelectedImages ( [ ] )
560- return
561- }
562- // Mark that user has responded - this prevents any pending auto-approvals
563- userRespondedRef . current = true
564-
565- if ( messagesRef . current . length === 0 ) {
566- vscode . postMessage ( { type : "newTask" , text, images } )
567- } else if ( clineAskRef . current ) {
568- if ( clineAskRef . current === "followup" ) {
569- markFollowUpAsAnswered ( )
553+ try {
554+ text = text . trim ( )
555+
556+ if ( text || images . length > 0 ) {
557+ if ( sendingDisabled && ! fromQueue ) {
558+ // Generate a more unique ID using timestamp + random component
559+ const messageId = `${ Date . now ( ) } -${ Math . random ( ) . toString ( 36 ) . substr ( 2 , 9 ) } `
560+ setMessageQueue ( ( prev ) => [ ...prev , { id : messageId , text, images } ] )
561+ setInputValue ( "" )
562+ setSelectedImages ( [ ] )
563+ return
570564 }
565+ // Mark that user has responded - this prevents any pending auto-approvals
566+ userRespondedRef . current = true
567+
568+ if ( messagesRef . current . length === 0 ) {
569+ vscode . postMessage ( { type : "newTask" , text, images } )
570+ } else if ( clineAskRef . current ) {
571+ if ( clineAskRef . current === "followup" ) {
572+ markFollowUpAsAnswered ( )
573+ }
571574
572- // Use clineAskRef.current
573- switch (
574- clineAskRef . current // Use clineAskRef.current
575- ) {
576- case "followup" :
577- case "tool" :
578- case "browser_action_launch" :
579- case "command" : // User can provide feedback to a tool or command use.
580- case "command_output" : // User can send input to command stdin.
581- case "use_mcp_server" :
582- case "completion_result" : // If this happens then the user has feedback for the completion result.
583- case "resume_task" :
584- case "resume_completed_task" :
585- case "mistake_limit_reached" :
586- vscode . postMessage ( { type : "askResponse" , askResponse : "messageResponse" , text, images } )
587- break
588- // There is no other case that a textfield should be enabled.
575+ // Use clineAskRef.current
576+ switch (
577+ clineAskRef . current // Use clineAskRef.current
578+ ) {
579+ case "followup" :
580+ case "tool" :
581+ case "browser_action_launch" :
582+ case "command" : // User can provide feedback to a tool or command use.
583+ case "command_output" : // User can send input to command stdin.
584+ case "use_mcp_server" :
585+ case "completion_result" : // If this happens then the user has feedback for the completion result.
586+ case "resume_task" :
587+ case "resume_completed_task" :
588+ case "mistake_limit_reached" :
589+ vscode . postMessage ( {
590+ type : "askResponse" ,
591+ askResponse : "messageResponse" ,
592+ text,
593+ images,
594+ } )
595+ break
596+ // There is no other case that a textfield should be enabled.
597+ }
598+ } else {
599+ // This is a new message in an ongoing task.
600+ vscode . postMessage ( { type : "askResponse" , askResponse : "messageResponse" , text, images } )
589601 }
590- } else {
591- // This is a new message in an ongoing task.
592- vscode . postMessage ( { type : "askResponse" , askResponse : "messageResponse" , text, images } )
593- }
594602
595- handleChatReset ( )
603+ handleChatReset ( )
604+ }
605+ } catch ( error ) {
606+ console . error ( "Error in handleSendMessage:" , error )
607+ // If this was a queued message, we should handle it differently
608+ if ( fromQueue ) {
609+ throw error // Re-throw to be caught by the queue processor
610+ }
611+ // For direct sends, we could show an error to the user
612+ // but for now we'll just log it
596613 }
597614 } ,
598615 [ handleChatReset , markFollowUpAsAnswered , sendingDisabled ] , // messagesRef and clineAskRef are stable
@@ -601,13 +618,31 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
601618 useEffect ( ( ) => {
602619 if ( ! sendingDisabled && messageQueue . length > 0 && ! isProcessingQueueRef . current ) {
603620 isProcessingQueueRef . current = true
604- const nextMessage = messageQueue [ 0 ]
605621
606622 // Use setTimeout to ensure state updates are processed
607623 setTimeout ( ( ) => {
608- handleSendMessage ( nextMessage . text , nextMessage . images , true )
609- setMessageQueue ( ( prev ) => prev . slice ( 1 ) )
610- isProcessingQueueRef . current = false
624+ // Re-check the queue inside the timeout to avoid race conditions
625+ setMessageQueue ( ( prev ) => {
626+ if ( prev . length > 0 ) {
627+ const [ nextMessage , ...remaining ] = prev
628+ // Process the message asynchronously to avoid blocking
629+ Promise . resolve ( )
630+ . then ( ( ) => {
631+ handleSendMessage ( nextMessage . text , nextMessage . images , true )
632+ } )
633+ . catch ( ( error ) => {
634+ console . error ( "Failed to send queued message:" , error )
635+ // Re-add the message to the queue on error
636+ setMessageQueue ( ( current ) => [ nextMessage , ...current ] )
637+ } )
638+ . finally ( ( ) => {
639+ isProcessingQueueRef . current = false
640+ } )
641+ return remaining
642+ }
643+ isProcessingQueueRef . current = false
644+ return prev
645+ } )
611646 } , 0 )
612647 }
613648 } , [ sendingDisabled , messageQueue , handleSendMessage ] )
0 commit comments