@@ -81,6 +81,8 @@ interface AIToolUseBatchProps {
8181
8282const AIToolUseBatch = memo ( ( { parts, isStreaming } : AIToolUseBatchProps ) => {
8383 const [ userApprovalOverride , setUserApprovalOverride ] = useState < string | null > ( null ) ;
84+ const partsRef = useRef ( parts ) ;
85+ partsRef . current = parts ;
8486
8587 // All parts in a batch have the same approval status (enforced by grouping logic in AIToolUseGroup)
8688 const firstTool = parts [ 0 ] . data ;
@@ -91,13 +93,13 @@ const AIToolUseBatch = memo(({ parts, isStreaming }: AIToolUseBatchProps) => {
9193 if ( ! isStreaming || effectiveApproval !== "needs-approval" ) return ;
9294
9395 const interval = setInterval ( ( ) => {
94- parts . forEach ( ( part ) => {
96+ partsRef . current . forEach ( ( part ) => {
9597 WaveAIModel . getInstance ( ) . toolUseKeepalive ( part . data . toolcallid ) ;
9698 } ) ;
9799 } , 4000 ) ;
98100
99101 return ( ) => clearInterval ( interval ) ;
100- } , [ isStreaming , effectiveApproval , parts ] ) ;
102+ } , [ isStreaming , effectiveApproval ] ) ;
101103
102104 const handleApprove = ( ) => {
103105 setUserApprovalOverride ( "user-approved" ) ;
@@ -231,6 +233,8 @@ const AIToolUse = memo(({ part, isStreaming }: AIToolUseProps) => {
231233 const showRestoreModal = restoreModalToolCallId === toolData . toolcallid ;
232234 const highlightTimeoutRef = useRef < NodeJS . Timeout | null > ( null ) ;
233235 const highlightedBlockIdRef = useRef < string | null > ( null ) ;
236+ const toolCallIdRef = useRef ( toolData . toolcallid ) ;
237+ toolCallIdRef . current = toolData . toolcallid ;
234238
235239 const statusIcon = toolData . status === "completed" ? "✓" : toolData . status === "error" ? "✗" : "•" ;
236240 const statusColor =
@@ -245,11 +249,11 @@ const AIToolUse = memo(({ part, isStreaming }: AIToolUseProps) => {
245249 if ( ! isStreaming || effectiveApproval !== "needs-approval" ) return ;
246250
247251 const interval = setInterval ( ( ) => {
248- WaveAIModel . getInstance ( ) . toolUseKeepalive ( toolData . toolcallid ) ;
252+ WaveAIModel . getInstance ( ) . toolUseKeepalive ( toolCallIdRef . current ) ;
249253 } , 4000 ) ;
250254
251255 return ( ) => clearInterval ( interval ) ;
252- } , [ isStreaming , effectiveApproval , toolData . toolcallid ] ) ;
256+ } , [ isStreaming , effectiveApproval ] ) ;
253257
254258 useEffect ( ( ) => {
255259 return ( ) => {
@@ -399,13 +403,17 @@ export const AIToolUseGroup = memo(({ parts, isStreaming }: AIToolUseGroupProps)
399403 const isFileOpPart = isFileOp ( part ) ;
400404 const partNeedsApproval = needsApproval ( part ) ;
401405
402- if ( isFileOpPart && partNeedsApproval && ! addedApprovalBatch ) {
403- groupedItems . push ( { type : "batch" , parts : readFileNeedsApproval } ) ;
404- addedApprovalBatch = true ;
405- } else if ( isFileOpPart && ! partNeedsApproval && ! addedOtherBatch ) {
406- groupedItems . push ( { type : "batch" , parts : readFileOther } ) ;
407- addedOtherBatch = true ;
408- } else if ( ! isFileOpPart ) {
406+ if ( isFileOpPart && partNeedsApproval ) {
407+ if ( ! addedApprovalBatch ) {
408+ groupedItems . push ( { type : "batch" , parts : readFileNeedsApproval } ) ;
409+ addedApprovalBatch = true ;
410+ }
411+ } else if ( isFileOpPart && ! partNeedsApproval ) {
412+ if ( ! addedOtherBatch ) {
413+ groupedItems . push ( { type : "batch" , parts : readFileOther } ) ;
414+ addedOtherBatch = true ;
415+ }
416+ } else {
409417 groupedItems . push ( { type : "single" , part } ) ;
410418 }
411419 }
0 commit comments