@@ -315,43 +315,64 @@ describe('sse-handlers tool lifecycle', () => {
315315 )
316316 } )
317317
318- it ( 'pre-persists browser tools as pending for the desktop authorization claim' , async ( ) => {
319- isSimExecuted . mockReturnValue ( false )
320- context . runId = 'run-1'
321-
322- await prePersistClientExecutableToolCall (
323- {
324- type : MothershipStreamV1EventType . tool ,
325- payload : {
326- toolCallId : 'browser-tool-1' ,
327- toolName : 'browser_list_tabs' ,
328- arguments : { } ,
329- executor : MothershipStreamV1ToolExecutor . client ,
330- mode : MothershipStreamV1ToolMode . async ,
331- phase : MothershipStreamV1ToolPhase . call ,
332- } ,
333- } satisfies StreamEvent ,
334- context ,
335- { } ,
336- execContext
337- )
338-
339- expect ( upsertAsyncToolCall ) . toHaveBeenCalledWith ( {
340- runId : 'run-1' ,
341- toolCallId : 'browser-tool-1' ,
342- toolName : 'browser_list_tabs' ,
343- args : { } ,
344- sealedContext : { __sealedClientToolContextV1 : 'sealed-context' } ,
345- status : MothershipStreamV1AsyncToolRecordStatus . pending ,
346- } )
347- expect ( sealClientToolContext ) . toHaveBeenCalledWith ( {
348- toolCallId : 'browser-tool-1' ,
349- runId : 'run-1' ,
350- userId : 'user-1' ,
351- registry : execContext . resolvedSecretTraceRegistry ,
352- toolInput : { } ,
353- } )
354- } )
318+ describe . each ( [ 'browser_list_tabs' , 'terminal' , 'import_local_files' , 'computer' ] ) (
319+ 'native %s pre-persistence' ,
320+ ( toolName ) => {
321+ it . each ( [ false , true ] ) (
322+ 'keeps the call pending for the desktop claim when approval gating is %s' ,
323+ async ( gated ) => {
324+ isSimExecuted . mockReturnValue ( false )
325+ toolRequiresApproval . mockReturnValue ( gated )
326+ context . runId = 'run-1'
327+ context . toolPermissions . enabled = gated
328+ const args =
329+ toolName === 'computer'
330+ ? { action : 'status' }
331+ : toolName === 'terminal'
332+ ? { operation : 'run' , command : 'pwd' }
333+ : { }
334+ const event = {
335+ type : MothershipStreamV1EventType . tool ,
336+ payload : {
337+ toolCallId : 'native-tool-1' ,
338+ toolName,
339+ arguments : args ,
340+ executor : MothershipStreamV1ToolExecutor . client ,
341+ mode : MothershipStreamV1ToolMode . async ,
342+ phase : MothershipStreamV1ToolPhase . call ,
343+ } ,
344+ } satisfies StreamEvent
345+
346+ await prePersistClientExecutableToolCall ( event , context , { } , execContext )
347+
348+ expect ( upsertAsyncToolCall ) . toHaveBeenCalledExactlyOnceWith ( {
349+ runId : 'run-1' ,
350+ toolCallId : 'native-tool-1' ,
351+ toolName,
352+ args,
353+ sealedContext : { __sealedClientToolContextV1 : 'sealed-context' } ,
354+ status : MothershipStreamV1AsyncToolRecordStatus . pending ,
355+ } )
356+ expect ( sealClientToolContext ) . toHaveBeenCalledWith ( {
357+ toolCallId : 'native-tool-1' ,
358+ runId : 'run-1' ,
359+ userId : 'user-1' ,
360+ registry : execContext . resolvedSecretTraceRegistry ,
361+ toolInput : args ,
362+ } )
363+ expect ( event . payload ) . toEqual ( {
364+ toolCallId : 'native-tool-1' ,
365+ toolName,
366+ arguments : args ,
367+ executor : MothershipStreamV1ToolExecutor . client ,
368+ mode : MothershipStreamV1ToolMode . async ,
369+ phase : MothershipStreamV1ToolPhase . call ,
370+ ...( gated ? { status : 'awaiting_approval' } : { } ) ,
371+ } )
372+ }
373+ )
374+ }
375+ )
355376
356377 it ( 'persists a gated sim tool and stamps the frame so a reload can still answer it' , async ( ) => {
357378 toolRequiresApproval . mockReturnValue ( true )
0 commit comments