@@ -342,43 +342,64 @@ describe('sse-handlers tool lifecycle', () => {
342342 )
343343 } )
344344
345- it ( 'pre-persists browser tools as pending for the desktop authorization claim' , async ( ) => {
346- isSimExecuted . mockReturnValue ( false )
347- context . runId = 'run-1'
345+ describe . each ( [ 'browser_list_tabs' , 'terminal' , 'import_local_files' , 'computer' ] ) (
346+ 'native %s pre-persistence' ,
347+ ( toolName ) => {
348+ it . each ( [ false , true ] ) (
349+ 'keeps the call pending for the desktop claim when approval gating is %s' ,
350+ async ( gated ) => {
351+ isSimExecuted . mockReturnValue ( false )
352+ toolRequiresApproval . mockReturnValue ( gated )
353+ context . runId = 'run-1'
354+ context . toolPermissions . enabled = gated
355+ const args =
356+ toolName === 'computer'
357+ ? { action : 'status' }
358+ : toolName === 'terminal'
359+ ? { operation : 'run' , command : 'pwd' }
360+ : { }
361+ const event = {
362+ type : MothershipStreamV1EventType . tool ,
363+ payload : {
364+ toolCallId : 'native-tool-1' ,
365+ toolName,
366+ arguments : args ,
367+ executor : MothershipStreamV1ToolExecutor . client ,
368+ mode : MothershipStreamV1ToolMode . async ,
369+ phase : MothershipStreamV1ToolPhase . call ,
370+ } ,
371+ } satisfies StreamEvent
348372
349- await prePersistClientExecutableToolCall (
350- {
351- type : MothershipStreamV1EventType . tool ,
352- payload : {
353- toolCallId : 'browser-tool-1' ,
354- toolName : 'browser_list_tabs' ,
355- arguments : { } ,
356- executor : MothershipStreamV1ToolExecutor . client ,
357- mode : MothershipStreamV1ToolMode . async ,
358- phase : MothershipStreamV1ToolPhase . call ,
359- } ,
360- } satisfies StreamEvent ,
361- context ,
362- { } ,
363- execContext
364- )
373+ await prePersistClientExecutableToolCall ( event , context , { } , execContext )
365374
366- expect ( upsertAsyncToolCall ) . toHaveBeenCalledWith ( {
367- runId : 'run-1' ,
368- toolCallId : 'browser-tool-1' ,
369- toolName : 'browser_list_tabs' ,
370- args : { } ,
371- sealedContext : { __sealedClientToolContextV1 : 'sealed-context' } ,
372- status : MothershipStreamV1AsyncToolRecordStatus . pending ,
373- } )
374- expect ( sealClientToolContext ) . toHaveBeenCalledWith ( {
375- toolCallId : 'browser-tool-1' ,
376- runId : 'run-1' ,
377- userId : 'user-1' ,
378- registry : execContext . resolvedSecretTraceRegistry ,
379- toolInput : { } ,
380- } )
381- } )
375+ expect ( upsertAsyncToolCall ) . toHaveBeenCalledExactlyOnceWith ( {
376+ runId : 'run-1' ,
377+ toolCallId : 'native-tool-1' ,
378+ toolName,
379+ args,
380+ sealedContext : { __sealedClientToolContextV1 : 'sealed-context' } ,
381+ status : MothershipStreamV1AsyncToolRecordStatus . pending ,
382+ } )
383+ expect ( sealClientToolContext ) . toHaveBeenCalledWith ( {
384+ toolCallId : 'native-tool-1' ,
385+ runId : 'run-1' ,
386+ userId : 'user-1' ,
387+ registry : execContext . resolvedSecretTraceRegistry ,
388+ toolInput : args ,
389+ } )
390+ expect ( event . payload ) . toEqual ( {
391+ toolCallId : 'native-tool-1' ,
392+ toolName,
393+ arguments : args ,
394+ executor : MothershipStreamV1ToolExecutor . client ,
395+ mode : MothershipStreamV1ToolMode . async ,
396+ phase : MothershipStreamV1ToolPhase . call ,
397+ ...( gated ? { status : 'awaiting_approval' } : { } ) ,
398+ } )
399+ }
400+ )
401+ }
402+ )
382403
383404 it ( 'persists a gated sim tool and stamps the frame so a reload can still answer it' , async ( ) => {
384405 toolRequiresApproval . mockReturnValue ( true )
0 commit comments