@@ -58,7 +58,7 @@ async def test_stdio_server():
58
58
server = MCPServerStdio ('python' , ['-m' , 'tests.mcp_server' ])
59
59
async with server :
60
60
tools = await server .list_tools ()
61
- assert len (tools ) == snapshot (13 )
61
+ assert len (tools ) == snapshot (16 )
62
62
assert tools [0 ].name == 'celsius_to_fahrenheit'
63
63
assert isinstance (tools [0 ].description , str )
64
64
assert tools [0 ].description .startswith ('Convert Celsius to Fahrenheit.' )
@@ -87,7 +87,7 @@ async def test_stdio_server_with_cwd():
87
87
server = MCPServerStdio ('python' , ['mcp_server.py' ], cwd = test_dir )
88
88
async with server :
89
89
tools = await server .list_tools ()
90
- assert len (tools ) == snapshot (13 )
90
+ assert len (tools ) == snapshot (16 )
91
91
92
92
93
93
async def test_process_tool_call () -> None :
@@ -254,8 +254,8 @@ async def test_log_level_unset():
254
254
assert server .log_level is None
255
255
async with server :
256
256
tools = await server .list_tools ()
257
- assert len (tools ) == snapshot (13 )
258
- assert tools [10 ].name == 'get_log_level'
257
+ assert len (tools ) == snapshot (16 )
258
+ assert tools [13 ].name == 'get_log_level'
259
259
260
260
result = await server .call_tool ('get_log_level' , {})
261
261
assert result == snapshot ('unset' )
@@ -421,6 +421,79 @@ async def test_tool_returning_text_resource(allow_model_requests: None, agent: A
421
421
)
422
422
423
423
424
+ @pytest .mark .vcr ()
425
+ async def test_tool_returning_text_resource_1 (allow_model_requests : None , agent : Agent ):
426
+ async with agent .run_mcp_servers ():
427
+ result = await agent .run ('Get me the product name' )
428
+ assert result .output == snapshot ('The product name is "PydanticAI".' )
429
+ assert result .all_messages () == snapshot (
430
+ [
431
+ ModelRequest (
432
+ parts = [
433
+ UserPromptPart (
434
+ content = 'Get me the product name' ,
435
+ timestamp = IsDatetime (),
436
+ )
437
+ ]
438
+ ),
439
+ ModelResponse (
440
+ parts = [
441
+ ToolCallPart (
442
+ tool_name = 'get_product_name_1' ,
443
+ args = '{}' ,
444
+ tool_call_id = 'call_LaiWltzI39sdquflqeuF0EyE' ,
445
+ )
446
+ ],
447
+ usage = Usage (
448
+ requests = 1 ,
449
+ request_tokens = 200 ,
450
+ response_tokens = 12 ,
451
+ total_tokens = 212 ,
452
+ details = {
453
+ 'accepted_prediction_tokens' : 0 ,
454
+ 'audio_tokens' : 0 ,
455
+ 'reasoning_tokens' : 0 ,
456
+ 'rejected_prediction_tokens' : 0 ,
457
+ 'cached_tokens' : 0 ,
458
+ },
459
+ ),
460
+ model_name = 'gpt-4o-2024-08-06' ,
461
+ timestamp = IsDatetime (),
462
+ vendor_id = 'chatcmpl-BRmhyweJVYonarb7s9ckIMSHf2vHo' ,
463
+ ),
464
+ ModelRequest (
465
+ parts = [
466
+ ToolReturnPart (
467
+ tool_name = 'get_product_name_1' ,
468
+ content = 'PydanticAI' ,
469
+ tool_call_id = 'call_LaiWltzI39sdquflqeuF0EyE' ,
470
+ timestamp = IsDatetime (),
471
+ )
472
+ ]
473
+ ),
474
+ ModelResponse (
475
+ parts = [TextPart (content = 'The product name is "PydanticAI".' )],
476
+ usage = Usage (
477
+ requests = 1 ,
478
+ request_tokens = 224 ,
479
+ response_tokens = 12 ,
480
+ total_tokens = 236 ,
481
+ details = {
482
+ 'accepted_prediction_tokens' : 0 ,
483
+ 'audio_tokens' : 0 ,
484
+ 'reasoning_tokens' : 0 ,
485
+ 'rejected_prediction_tokens' : 0 ,
486
+ 'cached_tokens' : 0 ,
487
+ },
488
+ ),
489
+ model_name = 'gpt-4o-2024-08-06' ,
490
+ timestamp = IsDatetime (),
491
+ vendor_id = 'chatcmpl-BRmhzqXFObpYwSzREMpJvX9kbDikR' ,
492
+ ),
493
+ ]
494
+ )
495
+
496
+
424
497
@pytest .mark .vcr ()
425
498
async def test_tool_returning_image_resource (allow_model_requests : None , agent : Agent , image_content : BinaryContent ):
426
499
async with agent .run_mcp_servers ():
@@ -501,6 +574,86 @@ async def test_tool_returning_image_resource(allow_model_requests: None, agent:
501
574
)
502
575
503
576
577
+ @pytest .mark .vcr ()
578
+ async def test_tool_returning_image_resource_1 (allow_model_requests : None , agent : Agent , image_content : BinaryContent ):
579
+ async with agent .run_mcp_servers ():
580
+ result = await agent .run ('Get me the image resource' )
581
+ assert result .output == snapshot (
582
+ 'This is an image of a sliced kiwi with a vibrant green interior and black seeds.'
583
+ )
584
+ assert result .all_messages () == snapshot (
585
+ [
586
+ ModelRequest (
587
+ parts = [
588
+ UserPromptPart (
589
+ content = 'Get me the image resource' ,
590
+ timestamp = IsDatetime (),
591
+ )
592
+ ]
593
+ ),
594
+ ModelResponse (
595
+ parts = [
596
+ ToolCallPart (
597
+ tool_name = 'get_image_resource_1' ,
598
+ args = '{}' ,
599
+ tool_call_id = 'call_nFsDHYDZigO0rOHqmChZ3pmt' ,
600
+ )
601
+ ],
602
+ usage = Usage (
603
+ requests = 1 ,
604
+ request_tokens = 191 ,
605
+ response_tokens = 12 ,
606
+ total_tokens = 203 ,
607
+ details = {
608
+ 'accepted_prediction_tokens' : 0 ,
609
+ 'audio_tokens' : 0 ,
610
+ 'reasoning_tokens' : 0 ,
611
+ 'rejected_prediction_tokens' : 0 ,
612
+ 'cached_tokens' : 0 ,
613
+ },
614
+ ),
615
+ model_name = 'gpt-4o-2024-08-06' ,
616
+ timestamp = IsDatetime (),
617
+ vendor_id = 'chatcmpl-BRlo7KYJVXuNZ5lLLdYcKZDsX2CHb' ,
618
+ ),
619
+ ModelRequest (
620
+ parts = [
621
+ ToolReturnPart (
622
+ tool_name = 'get_image_resource_1' ,
623
+ content = 'See file 1c8566' ,
624
+ tool_call_id = 'call_nFsDHYDZigO0rOHqmChZ3pmt' ,
625
+ timestamp = IsDatetime (),
626
+ ),
627
+ UserPromptPart (content = ['This is file 1c8566:' , image_content ], timestamp = IsDatetime ()),
628
+ ]
629
+ ),
630
+ ModelResponse (
631
+ parts = [
632
+ TextPart (
633
+ content = 'This is an image of a sliced kiwi with a vibrant green interior and black seeds.'
634
+ )
635
+ ],
636
+ usage = Usage (
637
+ requests = 1 ,
638
+ request_tokens = 1332 ,
639
+ response_tokens = 19 ,
640
+ total_tokens = 1351 ,
641
+ details = {
642
+ 'accepted_prediction_tokens' : 0 ,
643
+ 'audio_tokens' : 0 ,
644
+ 'reasoning_tokens' : 0 ,
645
+ 'rejected_prediction_tokens' : 0 ,
646
+ 'cached_tokens' : 0 ,
647
+ },
648
+ ),
649
+ model_name = 'gpt-4o-2024-08-06' ,
650
+ timestamp = IsDatetime (),
651
+ vendor_id = 'chatcmpl-BRloBGHh27w3fQKwxq4fX2cPuZJa9' ,
652
+ ),
653
+ ]
654
+ )
655
+
656
+
504
657
@pytest .mark .vcr ()
505
658
async def test_tool_returning_audio_resource (
506
659
allow_model_requests : None , agent : Agent , audio_content : BinaryContent , gemini_api_key : str
@@ -555,6 +708,60 @@ async def test_tool_returning_audio_resource(
555
708
)
556
709
557
710
711
+ @pytest .mark .vcr ()
712
+ async def test_tool_returning_audio_resource_1 (
713
+ allow_model_requests : None , agent : Agent , audio_content : BinaryContent , gemini_api_key : str
714
+ ):
715
+ model = GoogleModel ('gemini-2.5-pro-preview-03-25' , provider = GoogleProvider (api_key = gemini_api_key ))
716
+ async with agent .run_mcp_servers ():
717
+ result = await agent .run ("What's the content of the audio resource?" , model = model )
718
+ assert result .output == snapshot ('The audio resource contains a voice saying "Hello, my name is Marcelo."' )
719
+ assert result .all_messages () == snapshot (
720
+ [
721
+ ModelRequest (
722
+ parts = [UserPromptPart (content = "What's the content of the audio resource?" , timestamp = IsDatetime ())]
723
+ ),
724
+ ModelResponse (
725
+ parts = [ToolCallPart (tool_name = 'get_audio_resource_1' , args = {}, tool_call_id = IsStr ())],
726
+ usage = Usage (
727
+ requests = 1 ,
728
+ request_tokens = 383 ,
729
+ response_tokens = 12 ,
730
+ total_tokens = 520 ,
731
+ details = {'thoughts_tokens' : 125 , 'text_prompt_tokens' : 383 },
732
+ ),
733
+ model_name = 'models/gemini-2.5-pro-preview-05-06' ,
734
+ timestamp = IsDatetime (),
735
+ vendor_details = {'finish_reason' : 'STOP' },
736
+ ),
737
+ ModelRequest (
738
+ parts = [
739
+ ToolReturnPart (
740
+ tool_name = 'get_audio_resource_1' ,
741
+ content = 'See file 2d36ae' ,
742
+ tool_call_id = IsStr (),
743
+ timestamp = IsDatetime (),
744
+ ),
745
+ UserPromptPart (content = ['This is file 2d36ae:' , audio_content ], timestamp = IsDatetime ()),
746
+ ]
747
+ ),
748
+ ModelResponse (
749
+ parts = [TextPart (content = 'The audio resource contains a voice saying "Hello, my name is Marcelo."' )],
750
+ usage = Usage (
751
+ requests = 1 ,
752
+ request_tokens = 575 ,
753
+ response_tokens = 15 ,
754
+ total_tokens = 590 ,
755
+ details = {'text_prompt_tokens' : 431 , 'audio_prompt_tokens' : 144 },
756
+ ),
757
+ model_name = 'models/gemini-2.5-pro-preview-05-06' ,
758
+ timestamp = IsDatetime (),
759
+ vendor_details = {'finish_reason' : 'STOP' },
760
+ ),
761
+ ]
762
+ )
763
+
764
+
558
765
@pytest .mark .vcr ()
559
766
async def test_tool_returning_image (allow_model_requests : None , agent : Agent , image_content : BinaryContent ):
560
767
async with agent .run_mcp_servers ():
0 commit comments