@@ -296,7 +296,7 @@ export const sseHandlers: Record<string, SSEHandler> = {
296296 return
297297 }
298298
299- if ( ! isToolAvailableOnSimSide ( toolName ) ) {
299+ if ( ! isToolAvailableOnSimSide ( toolName ) && ! clientExecutable ) {
300300 return
301301 }
302302
@@ -396,16 +396,21 @@ export const sseHandlers: Record<string, SSEHandler> = {
396396 return
397397 }
398398
399- // Auto-allowed client-executable tool: client runs it, we wait for completion.
399+ // Client-executable tool: execute server-side if available, otherwise
400+ // delegate to the client (React UI) and wait for completion.
400401 if ( clientExecutable ) {
401- toolCall . status = 'executing'
402- const completion = await waitForToolCompletion (
403- toolCallId ,
404- options . timeout || STREAM_TIMEOUT_MS ,
405- options . abortSignal
406- )
407- handleClientCompletion ( toolCall , toolCallId , completion )
408- await emitSyntheticToolResult ( toolCallId , toolCall . name , completion , options )
402+ if ( isToolAvailableOnSimSide ( toolName ) ) {
403+ fireToolExecution ( )
404+ } else {
405+ toolCall . status = 'executing'
406+ const completion = await waitForToolCompletion (
407+ toolCallId ,
408+ options . timeout || STREAM_TIMEOUT_MS ,
409+ options . abortSignal
410+ )
411+ handleClientCompletion ( toolCall , toolCallId , completion )
412+ await emitSyntheticToolResult ( toolCallId , toolCall . name , completion , options )
413+ }
409414 return
410415 }
411416
@@ -548,7 +553,7 @@ export const subAgentHandlers: Record<string, SSEHandler> = {
548553 return
549554 }
550555
551- if ( ! isToolAvailableOnSimSide ( toolName ) ) {
556+ if ( ! isToolAvailableOnSimSide ( toolName ) && ! clientExecutable ) {
552557 return
553558 }
554559
@@ -643,14 +648,18 @@ export const subAgentHandlers: Record<string, SSEHandler> = {
643648 }
644649
645650 if ( clientExecutable ) {
646- toolCall . status = 'executing'
647- const completion = await waitForToolCompletion (
648- toolCallId ,
649- options . timeout || STREAM_TIMEOUT_MS ,
650- options . abortSignal
651- )
652- handleClientCompletion ( toolCall , toolCallId , completion )
653- await emitSyntheticToolResult ( toolCallId , toolCall . name , completion , options )
651+ if ( isToolAvailableOnSimSide ( toolName ) ) {
652+ fireToolExecution ( )
653+ } else {
654+ toolCall . status = 'executing'
655+ const completion = await waitForToolCompletion (
656+ toolCallId ,
657+ options . timeout || STREAM_TIMEOUT_MS ,
658+ options . abortSignal
659+ )
660+ handleClientCompletion ( toolCall , toolCallId , completion )
661+ await emitSyntheticToolResult ( toolCallId , toolCall . name , completion , options )
662+ }
654663 return
655664 }
656665
0 commit comments