pydantic-ai 0.4.7__tar.gz → 0.4.9__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pydantic-ai might be problematic. Click here for more details.

Files changed (346) hide show
  1. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/PKG-INFO +3 -3
  2. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/pyproject.toml +1 -1
  3. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/test_gemini.py +24 -8
  4. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/test_instrumented.py +44 -20
  5. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/test_ag_ui.py +110 -12
  6. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/test_mcp.py +14 -0
  7. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/test_streaming.py +36 -0
  8. pydantic_ai-0.4.9/tests/test_tenacity.py +572 -0
  9. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/test_toolsets.py +158 -1
  10. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/.gitignore +0 -0
  11. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/LICENSE +0 -0
  12. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/Makefile +0 -0
  13. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/README.md +0 -0
  14. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/__init__.py +0 -0
  15. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/assets/dummy.pdf +0 -0
  16. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/assets/kiwi.png +0 -0
  17. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/assets/marcelo.mp3 +0 -0
  18. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/assets/product_name.txt +0 -0
  19. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/assets/small_video.mp4 +0 -0
  20. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/cassettes/test_mcp/test_agent_with_server_not_running.yaml +0 -0
  21. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/cassettes/test_mcp/test_agent_with_stdio_server.yaml +0 -0
  22. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/cassettes/test_mcp/test_tool_returning_audio_resource.yaml +0 -0
  23. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/cassettes/test_mcp/test_tool_returning_audio_resource_link.yaml +0 -0
  24. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/cassettes/test_mcp/test_tool_returning_dict.yaml +0 -0
  25. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/cassettes/test_mcp/test_tool_returning_error.yaml +0 -0
  26. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/cassettes/test_mcp/test_tool_returning_image.yaml +0 -0
  27. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/cassettes/test_mcp/test_tool_returning_image_resource.yaml +0 -0
  28. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/cassettes/test_mcp/test_tool_returning_image_resource_link.yaml +0 -0
  29. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/cassettes/test_mcp/test_tool_returning_multiple_items.yaml +0 -0
  30. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/cassettes/test_mcp/test_tool_returning_none.yaml +0 -0
  31. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/cassettes/test_mcp/test_tool_returning_str.yaml +0 -0
  32. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/cassettes/test_mcp/test_tool_returning_text_resource.yaml +0 -0
  33. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/cassettes/test_mcp/test_tool_returning_text_resource_link.yaml +0 -0
  34. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/cassettes/test_settings/test_stop_settings[anthropic].yaml +0 -0
  35. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/cassettes/test_settings/test_stop_settings[bedrock].yaml +0 -0
  36. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/cassettes/test_settings/test_stop_settings[cohere].yaml +0 -0
  37. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/cassettes/test_settings/test_stop_settings[gemini].yaml +0 -0
  38. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/cassettes/test_settings/test_stop_settings[google].yaml +0 -0
  39. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/cassettes/test_settings/test_stop_settings[groq].yaml +0 -0
  40. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/cassettes/test_settings/test_stop_settings[mistral].yaml +0 -0
  41. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/cassettes/test_settings/test_stop_settings[openai].yaml +0 -0
  42. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/conftest.py +0 -0
  43. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/evals/__init__.py +0 -0
  44. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/evals/test_dataset.py +0 -0
  45. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/evals/test_evaluator_base.py +0 -0
  46. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/evals/test_evaluator_common.py +0 -0
  47. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/evals/test_evaluator_context.py +0 -0
  48. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/evals/test_evaluator_spec.py +0 -0
  49. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/evals/test_evaluators.py +0 -0
  50. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/evals/test_llm_as_a_judge.py +0 -0
  51. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/evals/test_otel.py +0 -0
  52. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/evals/test_render_numbers.py +0 -0
  53. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/evals/test_reporting.py +0 -0
  54. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/evals/test_reports.py +0 -0
  55. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/evals/test_utils.py +0 -0
  56. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/evals/utils.py +0 -0
  57. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/example_modules/README.md +0 -0
  58. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/example_modules/bank_database.py +0 -0
  59. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/example_modules/fake_database.py +0 -0
  60. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/example_modules/mcp_server.py +0 -0
  61. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/example_modules/weather_service.py +0 -0
  62. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/ext/__init__.py +0 -0
  63. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/ext/test_langchain.py +0 -0
  64. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/graph/__init__.py +0 -0
  65. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/graph/test_file_persistence.py +0 -0
  66. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/graph/test_graph.py +0 -0
  67. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/graph/test_mermaid.py +0 -0
  68. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/graph/test_persistence.py +0 -0
  69. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/graph/test_state.py +0 -0
  70. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/graph/test_utils.py +0 -0
  71. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/import_examples.py +0 -0
  72. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/json_body_serializer.py +0 -0
  73. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/mcp_server.py +0 -0
  74. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/__init__.py +0 -0
  75. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_anthropic/test_anthropic_model_empty_message_on_history.yaml +0 -0
  76. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_anthropic/test_anthropic_model_instructions.yaml +0 -0
  77. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_anthropic/test_anthropic_model_thinking_part.yaml +0 -0
  78. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_anthropic/test_anthropic_model_thinking_part_stream.yaml +0 -0
  79. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_anthropic/test_anthropic_prompted_output.yaml +0 -0
  80. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_anthropic/test_anthropic_prompted_output_multiple.yaml +0 -0
  81. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_anthropic/test_anthropic_text_output_function.yaml +0 -0
  82. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_anthropic/test_anthropic_tool_output.yaml +0 -0
  83. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_anthropic/test_anthropic_tool_with_thinking.yaml +0 -0
  84. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_anthropic/test_document_binary_content_input.yaml +0 -0
  85. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_anthropic/test_document_url_input.yaml +0 -0
  86. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_anthropic/test_extra_headers.yaml +0 -0
  87. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_anthropic/test_image_as_binary_content_tool_response.yaml +0 -0
  88. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_anthropic/test_image_url_input.yaml +0 -0
  89. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_anthropic/test_image_url_input_invalid_mime_type.yaml +0 -0
  90. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_anthropic/test_multiple_parallel_tool_calls.yaml +0 -0
  91. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_anthropic/test_text_document_url_input.yaml +0 -0
  92. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_bedrock/test_bedrock_empty_system_prompt.yaml +0 -0
  93. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_bedrock/test_bedrock_model.yaml +0 -0
  94. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_bedrock/test_bedrock_model_anthropic_model_without_tools.yaml +0 -0
  95. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_bedrock/test_bedrock_model_guardrail_config.yaml +0 -0
  96. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_bedrock/test_bedrock_model_instructions.yaml +0 -0
  97. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_bedrock/test_bedrock_model_iter_stream.yaml +0 -0
  98. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_bedrock/test_bedrock_model_max_tokens.yaml +0 -0
  99. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_bedrock/test_bedrock_model_other_parameters.yaml +0 -0
  100. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_bedrock/test_bedrock_model_performance_config.yaml +0 -0
  101. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_bedrock/test_bedrock_model_retry.yaml +0 -0
  102. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_bedrock/test_bedrock_model_stream.yaml +0 -0
  103. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_bedrock/test_bedrock_model_structured_output.yaml +0 -0
  104. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_bedrock/test_bedrock_model_thinking_part.yaml +0 -0
  105. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_bedrock/test_bedrock_model_thinking_part_stream.yaml +0 -0
  106. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_bedrock/test_bedrock_model_top_p.yaml +0 -0
  107. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_bedrock/test_bedrock_multiple_documents_in_history.yaml +0 -0
  108. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_bedrock/test_document_url_input.yaml +0 -0
  109. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_bedrock/test_image_as_binary_content_input.yaml +0 -0
  110. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_bedrock/test_image_url_input.yaml +0 -0
  111. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_bedrock/test_text_as_binary_content_input.yaml +0 -0
  112. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_bedrock/test_text_document_url_input.yaml +0 -0
  113. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_bedrock/test_video_as_binary_content_input.yaml +0 -0
  114. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_bedrock/test_video_url_input.yaml +0 -0
  115. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_cohere/test_cohere_model_instructions.yaml +0 -0
  116. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_cohere/test_cohere_model_thinking_part.yaml +0 -0
  117. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_cohere/test_request_simple_success_with_vcr.yaml +0 -0
  118. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_deepseek/test_deepseek_model_thinking_part.yaml +0 -0
  119. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_deepseek/test_deepseek_model_thinking_stream.yaml +0 -0
  120. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_download_item/test_download_item_application_octet_stream.yaml +0 -0
  121. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_download_item/test_download_item_audio_mpeg.yaml +0 -0
  122. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_download_item/test_download_item_no_content_type.yaml +0 -0
  123. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_gemini/test_document_url_input.yaml +0 -0
  124. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_gemini/test_gemini_additional_properties_is_false.yaml +0 -0
  125. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_gemini/test_gemini_additional_properties_is_true.yaml +0 -0
  126. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_gemini/test_gemini_drop_exclusive_maximum.yaml +0 -0
  127. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_gemini/test_gemini_exclusive_minimum_and_maximum.yaml +0 -0
  128. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_gemini/test_gemini_model_instructions.yaml +0 -0
  129. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_gemini/test_gemini_model_thinking_part.yaml +0 -0
  130. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_gemini/test_gemini_native_output.yaml +0 -0
  131. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_gemini/test_gemini_native_output_multiple.yaml +0 -0
  132. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_gemini/test_gemini_prompted_output.yaml +0 -0
  133. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_gemini/test_gemini_prompted_output_multiple.yaml +0 -0
  134. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_gemini/test_gemini_prompted_output_with_tools.yaml +0 -0
  135. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_gemini/test_gemini_text_output_function.yaml +0 -0
  136. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_gemini/test_gemini_tool_config_any_with_tool_without_args.yaml +0 -0
  137. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_gemini/test_gemini_tool_output.yaml +0 -0
  138. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_gemini/test_gemini_youtube_video_url_input.yaml +0 -0
  139. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_gemini/test_image_as_binary_content_input.yaml +0 -0
  140. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_gemini/test_image_as_binary_content_tool_response.yaml +0 -0
  141. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_gemini/test_image_url_input.yaml +0 -0
  142. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_gemini/test_labels_are_ignored_with_gla_provider.yaml +0 -0
  143. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_gemini/test_video_as_binary_content_input.yaml +0 -0
  144. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_gemini/test_video_url_input.yaml +0 -0
  145. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_gemini_vertex/test_labels.yaml +0 -0
  146. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_gemini_vertex/test_url_input[AudioUrl (gs)].yaml +0 -0
  147. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_gemini_vertex/test_url_input[AudioUrl].yaml +0 -0
  148. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_gemini_vertex/test_url_input[DocumentUrl (gs)].yaml +0 -0
  149. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_gemini_vertex/test_url_input[DocumentUrl].yaml +0 -0
  150. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_gemini_vertex/test_url_input[ImageUrl (gs)].yaml +0 -0
  151. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_gemini_vertex/test_url_input[ImageUrl].yaml +0 -0
  152. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_gemini_vertex/test_url_input[VideoUrl (YouTube)].yaml +0 -0
  153. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_gemini_vertex/test_url_input[VideoUrl (gs)].yaml +0 -0
  154. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_gemini_vertex/test_url_input[VideoUrl].yaml +0 -0
  155. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_gemini_vertex/test_url_input_force_download.yaml +0 -0
  156. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_model.yaml +0 -0
  157. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_model_document_url_input.yaml +0 -0
  158. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_model_empty_assistant_response.yaml +0 -0
  159. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_model_empty_user_prompt.yaml +0 -0
  160. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_model_image_as_binary_content_input.yaml +0 -0
  161. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_model_image_url_input.yaml +0 -0
  162. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_model_instructions.yaml +0 -0
  163. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_model_iter_stream.yaml +0 -0
  164. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_model_max_tokens.yaml +0 -0
  165. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_model_multiple_documents_in_history.yaml +0 -0
  166. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_model_retry.yaml +0 -0
  167. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_model_safety_settings.yaml +0 -0
  168. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_model_stream.yaml +0 -0
  169. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_model_structured_output.yaml +0 -0
  170. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_model_text_as_binary_content_input.yaml +0 -0
  171. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_model_text_document_url_input.yaml +0 -0
  172. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_model_thinking_config.yaml +0 -0
  173. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_model_thinking_part.yaml +0 -0
  174. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_model_thinking_part_iter.yaml +0 -0
  175. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_model_top_p.yaml +0 -0
  176. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_model_vertex_labels.yaml +0 -0
  177. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_model_vertex_provider.yaml +0 -0
  178. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_model_video_as_binary_content_input.yaml +0 -0
  179. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_model_video_as_binary_content_input_with_vendor_metadata.yaml +0 -0
  180. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_model_video_url_input.yaml +0 -0
  181. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_model_youtube_video_url_input_with_vendor_metadata.yaml +0 -0
  182. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_native_output.yaml +0 -0
  183. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_native_output_multiple.yaml +0 -0
  184. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_prompted_output.yaml +0 -0
  185. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_prompted_output_multiple.yaml +0 -0
  186. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_prompted_output_with_tools.yaml +0 -0
  187. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_text_output_function.yaml +0 -0
  188. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_timeout.yaml +0 -0
  189. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_tool_config_any_with_tool_without_args.yaml +0 -0
  190. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_tool_output.yaml +0 -0
  191. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_url_input[AudioUrl (gs)].yaml +0 -0
  192. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_url_input[AudioUrl].yaml +0 -0
  193. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_url_input[DocumentUrl (gs)].yaml +0 -0
  194. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_url_input[DocumentUrl].yaml +0 -0
  195. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_url_input[ImageUrl (gs)].yaml +0 -0
  196. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_url_input[ImageUrl].yaml +0 -0
  197. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_url_input[VideoUrl (YouTube)].yaml +0 -0
  198. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_url_input[VideoUrl (gs)].yaml +0 -0
  199. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_url_input[VideoUrl].yaml +0 -0
  200. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_google/test_google_url_input_force_download.yaml +0 -0
  201. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_groq/test_extra_headers.yaml +0 -0
  202. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_groq/test_groq_model_instructions.yaml +0 -0
  203. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_groq/test_groq_model_thinking_part.yaml +0 -0
  204. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_groq/test_groq_model_thinking_part_iter.yaml +0 -0
  205. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_groq/test_image_as_binary_content_input.yaml +0 -0
  206. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_groq/test_image_as_binary_content_tool_response.yaml +0 -0
  207. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_groq/test_image_url_input.yaml +0 -0
  208. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_huggingface/test_hf_model_instructions.yaml +0 -0
  209. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_huggingface/test_hf_model_thinking_part.yaml +0 -0
  210. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_huggingface/test_hf_model_thinking_part_iter.yaml +0 -0
  211. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_huggingface/test_image_as_binary_content_input.yaml +0 -0
  212. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_huggingface/test_image_url_input.yaml +0 -0
  213. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_huggingface/test_max_completion_tokens[Qwen-Qwen2.5-72B-Instruct].yaml +0 -0
  214. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_huggingface/test_max_completion_tokens[deepseek-ai-DeepSeek-R1-0528].yaml +0 -0
  215. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_huggingface/test_max_completion_tokens[meta-llama-Llama-3.3-70B-Instruct].yaml +0 -0
  216. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_huggingface/test_request_simple_success_with_vcr.yaml +0 -0
  217. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_huggingface/test_request_simple_usage.yaml +0 -0
  218. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_huggingface/test_simple_completion.yaml +0 -0
  219. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_huggingface/test_stream_completion.yaml +0 -0
  220. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_mistral/test_image_as_binary_content_tool_response.yaml +0 -0
  221. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_mistral/test_mistral_model_instructions.yaml +0 -0
  222. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_mistral/test_mistral_model_thinking_part.yaml +0 -0
  223. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_model_names/test_known_model_names.yaml +0 -0
  224. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai/test_audio_as_binary_content_input.yaml +0 -0
  225. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai/test_compatible_api_with_tool_calls_without_id.yaml +0 -0
  226. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai/test_document_as_binary_content_input.yaml +0 -0
  227. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai/test_document_url_input.yaml +0 -0
  228. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai/test_extra_headers.yaml +0 -0
  229. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai/test_image_as_binary_content_input.yaml +0 -0
  230. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai/test_image_as_binary_content_tool_response.yaml +0 -0
  231. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai/test_image_url_tool_response.yaml +0 -0
  232. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai/test_invalid_response.yaml +0 -0
  233. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai/test_max_completion_tokens[gpt-4.5-preview].yaml +0 -0
  234. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai/test_max_completion_tokens[gpt-4o-mini].yaml +0 -0
  235. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai/test_max_completion_tokens[o3-mini].yaml +0 -0
  236. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai/test_multiple_agent_tool_calls.yaml +0 -0
  237. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai/test_openai_audio_url_input.yaml +0 -0
  238. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai/test_openai_instructions.yaml +0 -0
  239. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai/test_openai_instructions_with_tool_calls_keep_instructions.yaml +0 -0
  240. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai/test_openai_model_thinking_part.yaml +0 -0
  241. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai/test_openai_model_thinking_part_iter.yaml +0 -0
  242. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai/test_openai_model_without_system_prompt.yaml +0 -0
  243. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai/test_openai_native_output.yaml +0 -0
  244. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai/test_openai_native_output_multiple.yaml +0 -0
  245. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai/test_openai_o1_mini_system_role[developer].yaml +0 -0
  246. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai/test_openai_o1_mini_system_role[system].yaml +0 -0
  247. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai/test_openai_prompted_output.yaml +0 -0
  248. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai/test_openai_prompted_output_multiple.yaml +0 -0
  249. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai/test_openai_responses_model_thinking_part.yaml +0 -0
  250. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai/test_openai_text_output_function.yaml +0 -0
  251. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai/test_openai_tool_output.yaml +0 -0
  252. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai/test_reasoning_model_with_temperature.yaml +0 -0
  253. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai/test_text_response.yaml +0 -0
  254. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai/test_user_id.yaml +0 -0
  255. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai/test_valid_response.yaml +0 -0
  256. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai_responses/test_audio_as_binary_content_input.yaml +0 -0
  257. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai_responses/test_image_as_binary_content_input.yaml +0 -0
  258. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai_responses/test_image_as_binary_content_tool_response.yaml +0 -0
  259. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai_responses/test_native_output.yaml +0 -0
  260. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai_responses/test_native_output_multiple.yaml +0 -0
  261. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai_responses/test_openai_responses_document_as_binary_content_input.yaml +0 -0
  262. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai_responses/test_openai_responses_document_url_input.yaml +0 -0
  263. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai_responses/test_openai_responses_image_url_input.yaml +0 -0
  264. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai_responses/test_openai_responses_model_builtin_tools.yaml +0 -0
  265. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai_responses/test_openai_responses_model_http_error.yaml +0 -0
  266. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai_responses/test_openai_responses_model_instructions.yaml +0 -0
  267. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai_responses/test_openai_responses_model_retry.yaml +0 -0
  268. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai_responses/test_openai_responses_model_simple_response.yaml +0 -0
  269. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai_responses/test_openai_responses_model_simple_response_with_tool_call.yaml +0 -0
  270. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai_responses/test_openai_responses_output_type.yaml +0 -0
  271. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai_responses/test_openai_responses_reasoning_effort.yaml +0 -0
  272. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai_responses/test_openai_responses_reasoning_generate_summary.yaml +0 -0
  273. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai_responses/test_openai_responses_stream.yaml +0 -0
  274. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai_responses/test_openai_responses_system_prompt.yaml +0 -0
  275. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai_responses/test_openai_responses_text_document_url_input.yaml +0 -0
  276. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai_responses/test_prompted_output.yaml +0 -0
  277. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai_responses/test_prompted_output_multiple.yaml +0 -0
  278. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai_responses/test_reasoning_model_with_temperature.yaml +0 -0
  279. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai_responses/test_text_output_function.yaml +0 -0
  280. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/cassettes/test_openai_responses/test_tool_output.yaml +0 -0
  281. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/mock_async_stream.py +0 -0
  282. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/test_anthropic.py +0 -0
  283. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/test_bedrock.py +0 -0
  284. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/test_cohere.py +0 -0
  285. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/test_deepseek.py +0 -0
  286. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/test_download_item.py +0 -0
  287. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/test_fallback.py +0 -0
  288. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/test_gemini_vertex.py +0 -0
  289. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/test_google.py +0 -0
  290. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/test_groq.py +0 -0
  291. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/test_huggingface.py +0 -0
  292. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/test_mcp_sampling.py +0 -0
  293. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/test_mistral.py +0 -0
  294. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/test_model.py +0 -0
  295. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/test_model_function.py +0 -0
  296. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/test_model_names.py +0 -0
  297. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/test_model_request_parameters.py +0 -0
  298. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/test_model_settings.py +0 -0
  299. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/test_model_test.py +0 -0
  300. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/test_openai.py +0 -0
  301. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/models/test_openai_responses.py +0 -0
  302. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/providers/__init__.py +0 -0
  303. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/providers/cassettes/test_azure/test_azure_provider_call.yaml +0 -0
  304. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/providers/cassettes/test_google_vertex/test_vertexai_provider.yaml +0 -0
  305. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/providers/cassettes/test_heroku/test_heroku_model_provider_claude_3_7_sonnet.yaml +0 -0
  306. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/providers/cassettes/test_openrouter/test_openrouter_with_google_model.yaml +0 -0
  307. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/providers/test_anthropic.py +0 -0
  308. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/providers/test_azure.py +0 -0
  309. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/providers/test_bedrock.py +0 -0
  310. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/providers/test_cohere.py +0 -0
  311. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/providers/test_deepseek.py +0 -0
  312. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/providers/test_fireworks.py +0 -0
  313. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/providers/test_github.py +0 -0
  314. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/providers/test_google_gla.py +0 -0
  315. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/providers/test_google_vertex.py +0 -0
  316. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/providers/test_grok.py +0 -0
  317. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/providers/test_groq.py +0 -0
  318. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/providers/test_heroku.py +0 -0
  319. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/providers/test_huggingface.py +0 -0
  320. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/providers/test_mistral.py +0 -0
  321. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/providers/test_moonshotai.py +0 -0
  322. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/providers/test_openai.py +0 -0
  323. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/providers/test_openrouter.py +0 -0
  324. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/providers/test_provider_names.py +0 -0
  325. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/providers/test_together.py +0 -0
  326. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/providers/test_vercel.py +0 -0
  327. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/test_a2a.py +0 -0
  328. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/test_agent.py +0 -0
  329. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/test_cli.py +0 -0
  330. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/test_deps.py +0 -0
  331. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/test_direct.py +0 -0
  332. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/test_examples.py +0 -0
  333. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/test_format_as_xml.py +0 -0
  334. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/test_history_processor.py +0 -0
  335. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/test_json_body_serializer.py +0 -0
  336. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/test_live.py +0 -0
  337. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/test_logfire.py +0 -0
  338. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/test_messages.py +0 -0
  339. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/test_parts_manager.py +0 -0
  340. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/test_settings.py +0 -0
  341. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/test_thinking_part.py +0 -0
  342. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/test_tools.py +0 -0
  343. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/test_usage_limits.py +0 -0
  344. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/test_utils.py +0 -0
  345. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/typed_agent.py +0 -0
  346. {pydantic_ai-0.4.7 → pydantic_ai-0.4.9}/tests/typed_graph.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pydantic-ai
3
- Version: 0.4.7
3
+ Version: 0.4.9
4
4
  Summary: Agent Framework / shim to use Pydantic with LLMs
5
5
  Project-URL: Homepage, https://ai.pydantic.dev
6
6
  Project-URL: Source, https://github.com/pydantic/pydantic-ai
@@ -28,11 +28,11 @@ Classifier: Topic :: Internet
28
28
  Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
29
29
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
30
30
  Requires-Python: >=3.9
31
- Requires-Dist: pydantic-ai-slim[ag-ui,anthropic,bedrock,cli,cohere,evals,google,groq,huggingface,mcp,mistral,openai,vertexai]==0.4.7
31
+ Requires-Dist: pydantic-ai-slim[ag-ui,anthropic,bedrock,cli,cohere,evals,google,groq,huggingface,mcp,mistral,openai,retries,vertexai]==0.4.9
32
32
  Provides-Extra: a2a
33
33
  Requires-Dist: fasta2a>=0.4.1; extra == 'a2a'
34
34
  Provides-Extra: examples
35
- Requires-Dist: pydantic-ai-examples==0.4.7; extra == 'examples'
35
+ Requires-Dist: pydantic-ai-examples==0.4.9; extra == 'examples'
36
36
  Provides-Extra: logfire
37
37
  Requires-Dist: logfire>=3.11.0; extra == 'logfire'
38
38
  Description-Content-Type: text/markdown
@@ -47,7 +47,7 @@ requires-python = ">=3.9"
47
47
 
48
48
  [tool.hatch.metadata.hooks.uv-dynamic-versioning]
49
49
  dependencies = [
50
- "pydantic-ai-slim[openai,vertexai,google,groq,anthropic,mistral,cohere,bedrock,huggingface,cli,mcp,evals,ag-ui]=={{ version }}",
50
+ "pydantic-ai-slim[openai,vertexai,google,groq,anthropic,mistral,cohere,bedrock,huggingface,cli,mcp,evals,ag-ui,retries]=={{ version }}",
51
51
  ]
52
52
 
53
53
  [tool.hatch.metadata.hooks.uv-dynamic-versioning.optional-dependencies]
@@ -194,7 +194,7 @@ async def test_require_response_tool(allow_model_requests: None):
194
194
 
195
195
  async def test_json_def_replaced(allow_model_requests: None):
196
196
  class Axis(BaseModel):
197
- label: str
197
+ label: str = Field(default='<unlabeled axis>', description='The label of the axis')
198
198
 
199
199
  class Chart(BaseModel):
200
200
  x_axis: Axis
@@ -213,8 +213,14 @@ async def test_json_def_replaced(allow_model_requests: None):
213
213
  {
214
214
  '$defs': {
215
215
  'Axis': {
216
- 'properties': {'label': {'title': 'Label', 'type': 'string'}},
217
- 'required': ['label'],
216
+ 'properties': {
217
+ 'label': {
218
+ 'default': '<unlabeled axis>',
219
+ 'description': 'The label of the axis',
220
+ 'title': 'Label',
221
+ 'type': 'string',
222
+ }
223
+ },
218
224
  'title': 'Axis',
219
225
  'type': 'object',
220
226
  },
@@ -268,17 +274,27 @@ async def test_json_def_replaced(allow_model_requests: None):
268
274
  'items': {
269
275
  'properties': {
270
276
  'lat': {'type': 'number'},
271
- 'lng': {'type': 'number'},
277
+ 'lng': {'default': 1.1, 'type': 'number'},
272
278
  'chart': {
273
279
  'properties': {
274
280
  'x_axis': {
275
- 'properties': {'label': {'type': 'string'}},
276
- 'required': ['label'],
281
+ 'properties': {
282
+ 'label': {
283
+ 'default': '<unlabeled axis>',
284
+ 'description': 'The label of the axis',
285
+ 'type': 'string',
286
+ }
287
+ },
277
288
  'type': 'object',
278
289
  },
279
290
  'y_axis': {
280
- 'properties': {'label': {'type': 'string'}},
281
- 'required': ['label'],
291
+ 'properties': {
292
+ 'label': {
293
+ 'default': '<unlabeled axis>',
294
+ 'description': 'The label of the axis',
295
+ 'type': 'string',
296
+ }
297
+ },
282
298
  'type': 'object',
283
299
  },
284
300
  },
@@ -26,6 +26,7 @@ from pydantic_ai.messages import (
26
26
  SystemPromptPart,
27
27
  TextPart,
28
28
  TextPartDelta,
29
+ ThinkingPart,
29
30
  ToolCallPart,
30
31
  ToolReturnPart,
31
32
  UserPromptPart,
@@ -150,7 +151,7 @@ async def test_instrumented_model(capfire: CaptureLogfire):
150
151
  'context': {'trace_id': 1, 'span_id': 1, 'is_remote': False},
151
152
  'parent': None,
152
153
  'start_time': 1000000000,
153
- 'end_time': 18000000000,
154
+ 'end_time': 16000000000,
154
155
  'attributes': {
155
156
  'gen_ai.operation.name': 'chat',
156
157
  'gen_ai.system': 'my_system',
@@ -284,7 +285,7 @@ Fix the errors and try again.\
284
285
  'index': 0,
285
286
  'message': {
286
287
  'role': 'assistant',
287
- 'content': 'text1',
288
+ 'content': [{'kind': 'text', 'text': 'text1'}, {'kind': 'text', 'text': 'text2'}],
288
289
  'tool_calls': [
289
290
  {
290
291
  'id': 'tool_call_1',
@@ -308,17 +309,6 @@ Fix the errors and try again.\
308
309
  'span_id': 1,
309
310
  'trace_flags': 1,
310
311
  },
311
- {
312
- 'body': {'index': 0, 'message': {'role': 'assistant', 'content': 'text2'}},
313
- 'severity_number': 9,
314
- 'severity_text': None,
315
- 'attributes': {'gen_ai.system': 'my_system', 'event.name': 'gen_ai.choice'},
316
- 'timestamp': 16000000000,
317
- 'observed_timestamp': 17000000000,
318
- 'trace_id': 1,
319
- 'span_id': 1,
320
- 'trace_flags': 1,
321
- },
322
312
  ]
323
313
  )
324
314
 
@@ -641,11 +631,13 @@ Fix the errors and try again.\
641
631
  'gen_ai.system': 'my_system',
642
632
  },
643
633
  {
644
- 'event.name': 'gen_ai.choice',
645
634
  'index': 0,
646
635
  'message': {
647
636
  'role': 'assistant',
648
- 'content': 'text1',
637
+ 'content': [
638
+ {'kind': 'text', 'text': 'text1'},
639
+ {'kind': 'text', 'text': 'text2'},
640
+ ],
649
641
  'tool_calls': [
650
642
  {
651
643
  'id': 'tool_call_1',
@@ -660,12 +652,7 @@ Fix the errors and try again.\
660
652
  ],
661
653
  },
662
654
  'gen_ai.system': 'my_system',
663
- },
664
- {
665
655
  'event.name': 'gen_ai.choice',
666
- 'index': 0,
667
- 'message': {'role': 'assistant', 'content': 'text2'},
668
- 'gen_ai.system': 'my_system',
669
656
  },
670
657
  ]
671
658
  )
@@ -879,6 +866,7 @@ def test_messages_without_content(document_content: BinaryContent):
879
866
  },
880
867
  {
881
868
  'role': 'assistant',
869
+ 'content': [{'kind': 'text'}],
882
870
  'gen_ai.message.index': 1,
883
871
  'event.name': 'gen_ai.assistant.message',
884
872
  },
@@ -897,6 +885,7 @@ def test_messages_without_content(document_content: BinaryContent):
897
885
  },
898
886
  {
899
887
  'role': 'assistant',
888
+ 'content': [{'kind': 'text'}],
900
889
  'tool_calls': [
901
890
  {
902
891
  'id': IsStr(),
@@ -935,3 +924,38 @@ def test_messages_without_content(document_content: BinaryContent):
935
924
  },
936
925
  ]
937
926
  )
927
+
928
+
929
+ def test_message_with_thinking_parts():
930
+ messages: list[ModelMessage] = [
931
+ ModelResponse(parts=[TextPart('text1'), ThinkingPart('thinking1'), TextPart('text2')]),
932
+ ModelResponse(parts=[ThinkingPart('thinking2')]),
933
+ ModelResponse(parts=[ThinkingPart('thinking3'), TextPart('text3')]),
934
+ ]
935
+ settings = InstrumentationSettings()
936
+ assert [InstrumentedModel.event_to_dict(e) for e in settings.messages_to_otel_events(messages)] == snapshot(
937
+ [
938
+ {
939
+ 'role': 'assistant',
940
+ 'content': [
941
+ {'kind': 'text', 'text': 'text1'},
942
+ {'kind': 'thinking', 'text': 'thinking1'},
943
+ {'kind': 'text', 'text': 'text2'},
944
+ ],
945
+ 'gen_ai.message.index': 0,
946
+ 'event.name': 'gen_ai.assistant.message',
947
+ },
948
+ {
949
+ 'role': 'assistant',
950
+ 'content': [{'kind': 'thinking', 'text': 'thinking2'}],
951
+ 'gen_ai.message.index': 1,
952
+ 'event.name': 'gen_ai.assistant.message',
953
+ },
954
+ {
955
+ 'role': 'assistant',
956
+ 'content': [{'kind': 'thinking', 'text': 'thinking3'}, {'kind': 'text', 'text': 'text3'}],
957
+ 'gen_ai.message.index': 2,
958
+ 'event.name': 'gen_ai.assistant.message',
959
+ },
960
+ ]
961
+ )
@@ -7,6 +7,7 @@ import contextlib
7
7
  import json
8
8
  import uuid
9
9
  from collections.abc import AsyncIterator
10
+ from dataclasses import dataclass
10
11
  from http import HTTPStatus
11
12
  from typing import Any
12
13
 
@@ -17,7 +18,9 @@ from dirty_equals import IsStr
17
18
  from inline_snapshot import snapshot
18
19
  from pydantic import BaseModel
19
20
 
21
+ from pydantic_ai._run_context import RunContext
20
22
  from pydantic_ai.agent import Agent
23
+ from pydantic_ai.exceptions import UserError
21
24
  from pydantic_ai.messages import ModelMessage
22
25
  from pydantic_ai.models.function import (
23
26
  AgentInfo,
@@ -27,8 +30,9 @@ from pydantic_ai.models.function import (
27
30
  DeltaToolCalls,
28
31
  FunctionModel,
29
32
  )
33
+ from pydantic_ai.models.test import TestModel
30
34
  from pydantic_ai.output import OutputDataT
31
- from pydantic_ai.tools import AgentDepsT
35
+ from pydantic_ai.tools import AgentDepsT, ToolDefinition
32
36
 
33
37
  from .conftest import IsSameStr
34
38
 
@@ -180,7 +184,7 @@ def create_input(
180
184
  thread_id=thread_id,
181
185
  run_id=uuid_str(),
182
186
  messages=list(messages),
183
- state=state,
187
+ state=dict(state) if state else {},
184
188
  context=[],
185
189
  tools=tools or [],
186
190
  forwarded_props=None,
@@ -1050,9 +1054,19 @@ async def test_tool_local_then_ag_ui() -> None:
1050
1054
  async def test_request_with_state() -> None:
1051
1055
  """Test request with state modification."""
1052
1056
 
1057
+ seen_states: list[int] = []
1058
+
1059
+ async def store_state(
1060
+ ctx: RunContext[StateDeps[StateInt]], tool_defs: list[ToolDefinition]
1061
+ ) -> list[ToolDefinition]:
1062
+ seen_states.append(ctx.deps.state.value)
1063
+ ctx.deps.state.value += 1
1064
+ return tool_defs
1065
+
1053
1066
  agent: Agent[StateDeps[StateInt], str] = Agent(
1054
1067
  model=FunctionModel(stream_function=simple_stream),
1055
1068
  deps_type=StateDeps[StateInt], # type: ignore[reportUnknownArgumentType]
1069
+ prepare_tools=store_state,
1056
1070
  )
1057
1071
  adapter = _Adapter(agent=agent)
1058
1072
  run_inputs = [
@@ -1074,32 +1088,101 @@ async def test_request_with_state() -> None:
1074
1088
  id='msg_3',
1075
1089
  content='Hello, how are you?',
1076
1090
  ),
1091
+ ),
1092
+ create_input(
1093
+ UserMessage(
1094
+ id='msg_4',
1095
+ content='Hello, how are you?',
1096
+ ),
1077
1097
  state=StateInt(value=42),
1078
1098
  ),
1079
1099
  ]
1080
1100
 
1081
- deps = StateDeps(StateInt())
1101
+ deps = StateDeps(StateInt(value=0))
1082
1102
 
1083
- last_value = deps.state.value
1084
1103
  for run_input in run_inputs:
1085
1104
  events = list[dict[str, Any]]()
1086
1105
  async for event in adapter.run(run_input, deps=deps):
1087
1106
  events.append(json.loads(event.removeprefix('data: ')))
1088
1107
 
1089
1108
  assert events == simple_result()
1090
- assert deps.state.value == run_input.state.value if run_input.state is not None else last_value
1091
- last_value = deps.state.value
1109
+ assert seen_states == snapshot(
1110
+ [
1111
+ 41, # run msg_1, prepare_tools call 1
1112
+ 42, # run msg_1, prepare_tools call 2
1113
+ 0, # run msg_2, prepare_tools call 1
1114
+ 1, # run msg_2, prepare_tools call 2
1115
+ 0, # run msg_3, prepare_tools call 1
1116
+ 1, # run msg_3, prepare_tools call 2
1117
+ 42, # run msg_4, prepare_tools call 1
1118
+ 43, # run msg_4, prepare_tools call 2
1119
+ ]
1120
+ )
1121
+
1122
+
1123
+ async def test_request_with_state_without_handler() -> None:
1124
+ agent = Agent(model=FunctionModel(stream_function=simple_stream))
1125
+ adapter = _Adapter(agent=agent)
1126
+ run_input = create_input(
1127
+ UserMessage(
1128
+ id='msg_1',
1129
+ content='Hello, how are you?',
1130
+ ),
1131
+ state=StateInt(value=41),
1132
+ )
1133
+
1134
+ with pytest.raises(
1135
+ UserError,
1136
+ match='AG-UI state is provided but `deps` of type `NoneType` does not implement the `StateHandler` protocol: it needs to be a dataclass with a non-optional `state` field.',
1137
+ ):
1138
+ async for _ in adapter.run(run_input):
1139
+ pass
1140
+
1141
+
1142
+ async def test_request_with_state_with_custom_handler() -> None:
1143
+ @dataclass
1144
+ class CustomStateDeps:
1145
+ state: dict[str, Any]
1146
+
1147
+ seen_states: list[dict[str, Any]] = []
1148
+
1149
+ async def store_state(ctx: RunContext[CustomStateDeps], tool_defs: list[ToolDefinition]) -> list[ToolDefinition]:
1150
+ seen_states.append(ctx.deps.state)
1151
+ return tool_defs
1152
+
1153
+ agent: Agent[CustomStateDeps, str] = Agent(
1154
+ model=FunctionModel(stream_function=simple_stream),
1155
+ deps_type=CustomStateDeps,
1156
+ prepare_tools=store_state,
1157
+ )
1158
+ adapter = _Adapter(agent=agent)
1159
+ run_input = create_input(
1160
+ UserMessage(
1161
+ id='msg_1',
1162
+ content='Hello, how are you?',
1163
+ ),
1164
+ state={'value': 42},
1165
+ )
1166
+
1167
+ async for _ in adapter.run(run_input, deps=CustomStateDeps(state={'value': 0})):
1168
+ pass
1092
1169
 
1093
- assert deps.state.value == 42
1170
+ assert seen_states[-1] == {'value': 42}
1094
1171
 
1095
1172
 
1096
1173
  async def test_concurrent_runs() -> None:
1097
1174
  """Test concurrent execution of multiple runs."""
1098
1175
  import asyncio
1099
1176
 
1100
- agent = Agent(
1101
- model=FunctionModel(stream_function=simple_stream),
1177
+ agent: Agent[StateDeps[StateInt], str] = Agent(
1178
+ model=TestModel(),
1179
+ deps_type=StateDeps[StateInt], # type: ignore[reportUnknownArgumentType]
1102
1180
  )
1181
+
1182
+ @agent.tool
1183
+ async def get_state(ctx: RunContext[StateDeps[StateInt]]) -> int:
1184
+ return ctx.deps.state.value
1185
+
1103
1186
  adapter = _Adapter(agent=agent)
1104
1187
  concurrent_tasks: list[asyncio.Task[list[dict[str, Any]]]] = []
1105
1188
 
@@ -1109,10 +1192,11 @@ async def test_concurrent_runs() -> None:
1109
1192
  id=f'msg_{i}',
1110
1193
  content=f'Message {i}',
1111
1194
  ),
1195
+ state=StateInt(value=i),
1112
1196
  thread_id=f'test_thread_{i}',
1113
1197
  )
1114
1198
 
1115
- task = asyncio.create_task(collect_events_from_adapter(adapter, run_input))
1199
+ task = asyncio.create_task(collect_events_from_adapter(adapter, run_input, deps=StateDeps(StateInt())))
1116
1200
  concurrent_tasks.append(task)
1117
1201
 
1118
1202
  results = await asyncio.gather(*concurrent_tasks)
@@ -1121,9 +1205,23 @@ async def test_concurrent_runs() -> None:
1121
1205
  for i, events in enumerate(results):
1122
1206
  assert events == [
1123
1207
  {'type': 'RUN_STARTED', 'threadId': f'test_thread_{i}', 'runId': (run_id := IsSameStr())},
1208
+ {
1209
+ 'type': 'TOOL_CALL_START',
1210
+ 'toolCallId': (tool_call_id := IsSameStr()),
1211
+ 'toolCallName': 'get_state',
1212
+ 'parentMessageId': IsStr(),
1213
+ },
1214
+ {'type': 'TOOL_CALL_END', 'toolCallId': tool_call_id},
1215
+ {
1216
+ 'type': 'TOOL_CALL_RESULT',
1217
+ 'messageId': IsStr(),
1218
+ 'toolCallId': tool_call_id,
1219
+ 'content': str(i),
1220
+ 'role': 'tool',
1221
+ },
1124
1222
  {'type': 'TEXT_MESSAGE_START', 'messageId': (message_id := IsSameStr()), 'role': 'assistant'},
1125
- {'type': 'TEXT_MESSAGE_CONTENT', 'messageId': message_id, 'delta': 'success '},
1126
- {'type': 'TEXT_MESSAGE_CONTENT', 'messageId': message_id, 'delta': '(no tool calls)'},
1223
+ {'type': 'TEXT_MESSAGE_CONTENT', 'messageId': message_id, 'delta': '{"get_s'},
1224
+ {'type': 'TEXT_MESSAGE_CONTENT', 'messageId': message_id, 'delta': 'tate":' + str(i) + '}'},
1127
1225
  {'type': 'TEXT_MESSAGE_END', 'messageId': message_id},
1128
1226
  {'type': 'RUN_FINISHED', 'threadId': f'test_thread_{i}', 'runId': run_id},
1129
1227
  ]
@@ -91,6 +91,20 @@ async def test_reentrant_context_manager():
91
91
  pass
92
92
 
93
93
 
94
+ async def test_context_manager_initialization_error() -> None:
95
+ """Test if streams are closed if client fails to initialize."""
96
+ server = MCPServerStdio('python', ['-m', 'tests.mcp_server'])
97
+ from mcp.client.session import ClientSession
98
+
99
+ with patch.object(ClientSession, 'initialize', side_effect=Exception):
100
+ with pytest.raises(Exception):
101
+ async with server:
102
+ pass
103
+
104
+ assert server._read_stream._closed # pyright: ignore[reportPrivateUsage]
105
+ assert server._write_stream._closed # pyright: ignore[reportPrivateUsage]
106
+
107
+
94
108
  async def test_stdio_server_with_tool_prefix(run_context: RunContext[int]):
95
109
  server = MCPServerStdio('python', ['-m', 'tests.mcp_server'], tool_prefix='foo')
96
110
  async with server:
@@ -1108,6 +1108,42 @@ async def test_iter_stream_structured_output():
1108
1108
  )
1109
1109
 
1110
1110
 
1111
+ async def test_iter_stream_output_tool_dont_hit_retry_limit():
1112
+ class CityLocation(BaseModel):
1113
+ city: str
1114
+ country: str | None = None
1115
+
1116
+ async def text_stream(_messages: list[ModelMessage], agent_info: AgentInfo) -> AsyncIterator[DeltaToolCalls]:
1117
+ """Stream partial JSON data that will initially fail validation."""
1118
+ assert agent_info.output_tools is not None
1119
+ assert len(agent_info.output_tools) == 1
1120
+ name = agent_info.output_tools[0].name
1121
+
1122
+ yield {0: DeltaToolCall(name=name)}
1123
+ yield {0: DeltaToolCall(json_args='{"c')}
1124
+ yield {0: DeltaToolCall(json_args='ity":')}
1125
+ yield {0: DeltaToolCall(json_args=' "Mex')}
1126
+ yield {0: DeltaToolCall(json_args='ico City",')}
1127
+ yield {0: DeltaToolCall(json_args=' "cou')}
1128
+ yield {0: DeltaToolCall(json_args='ntry": "Mexico"}')}
1129
+
1130
+ agent = Agent(FunctionModel(stream_function=text_stream), output_type=CityLocation)
1131
+
1132
+ async with agent.iter('Generate city info') as run:
1133
+ async for node in run:
1134
+ if agent.is_model_request_node(node):
1135
+ async with node.stream(run.ctx) as stream:
1136
+ assert [c async for c in stream.stream_output(debounce_by=None)] == snapshot(
1137
+ [
1138
+ CityLocation(city='Mex'),
1139
+ CityLocation(city='Mexico City'),
1140
+ CityLocation(city='Mexico City'),
1141
+ CityLocation(city='Mexico City', country='Mexico'),
1142
+ CityLocation(city='Mexico City', country='Mexico'),
1143
+ ]
1144
+ )
1145
+
1146
+
1111
1147
  def test_function_tool_event_tool_call_id_properties():
1112
1148
  """Ensure that the `tool_call_id` property on function tool events mirrors the underlying part's ID."""
1113
1149
  # Prepare a ToolCallPart with a fixed ID