@@ -291,6 +291,67 @@ describe("NativeToolCallParser", () => {
291291 } )
292292 } )
293293 } )
294+
295+ describe ( "fetch_web_content tool" , ( ) => {
296+ it ( "should parse fetch_web_content with url and prompt" , ( ) => {
297+ const toolCall = {
298+ id : "toolu_fetch_1" ,
299+ name : "fetch_web_content" as const ,
300+ arguments : JSON . stringify ( {
301+ url : "https://example.com" ,
302+ prompt : "Find the main heading" ,
303+ } ) ,
304+ }
305+
306+ const result = NativeToolCallParser . parseToolCall ( toolCall )
307+
308+ expect ( result ) . not . toBeNull ( )
309+ expect ( result ?. type ) . toBe ( "tool_use" )
310+ if ( result ?. type === "tool_use" ) {
311+ expect ( result . nativeArgs ) . toBeDefined ( )
312+ const nativeArgs = result . nativeArgs as { url : string ; prompt ?: string }
313+ expect ( nativeArgs . url ) . toBe ( "https://example.com" )
314+ expect ( nativeArgs . prompt ) . toBe ( "Find the main heading" )
315+ }
316+ } )
317+
318+ it ( "should parse fetch_web_content with url only (no prompt)" , ( ) => {
319+ const toolCall = {
320+ id : "toolu_fetch_2" ,
321+ name : "fetch_web_content" as const ,
322+ arguments : JSON . stringify ( {
323+ url : "https://api.example.com/status" ,
324+ prompt : null ,
325+ } ) ,
326+ }
327+
328+ const result = NativeToolCallParser . parseToolCall ( toolCall )
329+
330+ expect ( result ) . not . toBeNull ( )
331+ expect ( result ?. type ) . toBe ( "tool_use" )
332+ if ( result ?. type === "tool_use" ) {
333+ expect ( result . nativeArgs ) . toBeDefined ( )
334+ const nativeArgs = result . nativeArgs as { url : string ; prompt ?: string | null }
335+ expect ( nativeArgs . url ) . toBe ( "https://api.example.com/status" )
336+ expect ( nativeArgs . prompt ) . toBeNull ( )
337+ }
338+ } )
339+
340+ it ( "should return null when url is missing" , ( ) => {
341+ const toolCall = {
342+ id : "toolu_fetch_3" ,
343+ name : "fetch_web_content" as const ,
344+ arguments : JSON . stringify ( {
345+ prompt : "some prompt" ,
346+ } ) ,
347+ }
348+
349+ const result = NativeToolCallParser . parseToolCall ( toolCall )
350+
351+ // Should return null because nativeArgs can't be constructed without url
352+ expect ( result ) . toBeNull ( )
353+ } )
354+ } )
294355 } )
295356
296357 describe ( "processStreamingChunk" , ( ) => {
@@ -311,6 +372,22 @@ describe("NativeToolCallParser", () => {
311372 expect ( nativeArgs . path ) . toBe ( "src/test.ts" )
312373 } )
313374 } )
375+
376+ describe ( "fetch_web_content tool" , ( ) => {
377+ it ( "should emit a partial ToolUse with nativeArgs.url during streaming" , ( ) => {
378+ const id = "toolu_streaming_fetch_1"
379+ NativeToolCallParser . startStreamingToolCall ( id , "fetch_web_content" )
380+
381+ const fullArgs = JSON . stringify ( { url : "https://example.com" , prompt : "Find info" } )
382+ const result = NativeToolCallParser . processStreamingChunk ( id , fullArgs )
383+
384+ expect ( result ) . not . toBeNull ( )
385+ expect ( result ?. nativeArgs ) . toBeDefined ( )
386+ const nativeArgs = result ?. nativeArgs as { url : string ; prompt ?: string }
387+ expect ( nativeArgs . url ) . toBe ( "https://example.com" )
388+ expect ( nativeArgs . prompt ) . toBe ( "Find info" )
389+ } )
390+ } )
314391 } )
315392
316393 describe ( "finalizeStreamingToolCall" , ( ) => {
@@ -342,5 +419,53 @@ describe("NativeToolCallParser", () => {
342419 }
343420 } )
344421 } )
422+
423+ describe ( "fetch_web_content tool" , ( ) => {
424+ it ( "should parse fetch_web_content args on finalize" , ( ) => {
425+ const id = "toolu_finalize_fetch_1"
426+ NativeToolCallParser . startStreamingToolCall ( id , "fetch_web_content" )
427+
428+ NativeToolCallParser . processStreamingChunk (
429+ id ,
430+ JSON . stringify ( {
431+ url : "https://docs.example.com/api" ,
432+ prompt : "Find authentication methods" ,
433+ } ) ,
434+ )
435+
436+ const result = NativeToolCallParser . finalizeStreamingToolCall ( id )
437+
438+ expect ( result ) . not . toBeNull ( )
439+ expect ( result ?. type ) . toBe ( "tool_use" )
440+ if ( result ?. type === "tool_use" ) {
441+ const nativeArgs = result . nativeArgs as { url : string ; prompt ?: string }
442+ expect ( nativeArgs . url ) . toBe ( "https://docs.example.com/api" )
443+ expect ( nativeArgs . prompt ) . toBe ( "Find authentication methods" )
444+ }
445+ } )
446+
447+ it ( "should parse fetch_web_content with null prompt on finalize" , ( ) => {
448+ const id = "toolu_finalize_fetch_2"
449+ NativeToolCallParser . startStreamingToolCall ( id , "fetch_web_content" )
450+
451+ NativeToolCallParser . processStreamingChunk (
452+ id ,
453+ JSON . stringify ( {
454+ url : "https://api.example.com/status" ,
455+ prompt : null ,
456+ } ) ,
457+ )
458+
459+ const result = NativeToolCallParser . finalizeStreamingToolCall ( id )
460+
461+ expect ( result ) . not . toBeNull ( )
462+ expect ( result ?. type ) . toBe ( "tool_use" )
463+ if ( result ?. type === "tool_use" ) {
464+ const nativeArgs = result . nativeArgs as { url : string ; prompt ?: string | null }
465+ expect ( nativeArgs . url ) . toBe ( "https://api.example.com/status" )
466+ expect ( nativeArgs . prompt ) . toBeNull ( )
467+ }
468+ } )
469+ } )
345470 } )
346471} )
0 commit comments