pydantic-ai 0.2.3__tar.gz → 0.2.5__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 (216) hide show
  1. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/.gitignore +2 -0
  2. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/Makefile +4 -0
  3. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/PKG-INFO +3 -3
  4. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/pyproject.toml +4 -3
  5. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/conftest.py +8 -3
  6. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/evals/test_dataset.py +4 -4
  7. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/evals/test_evaluator_base.py +4 -3
  8. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/evals/test_evaluator_common.py +33 -19
  9. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/evals/test_evaluators.py +36 -9
  10. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/evals/test_render_numbers.py +2 -2
  11. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/evals/test_utils.py +2 -2
  12. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/graph/test_graph.py +1 -1
  13. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/graph/test_mermaid.py +1 -1
  14. pydantic_ai-0.2.5/tests/models/cassettes/test_google/test_google_model.yaml +67 -0
  15. pydantic_ai-0.2.5/tests/models/cassettes/test_google/test_google_model_document_url_input.yaml +351 -0
  16. pydantic_ai-0.2.5/tests/models/cassettes/test_google/test_google_model_image_as_binary_content_input.yaml +71 -0
  17. pydantic_ai-0.2.5/tests/models/cassettes/test_google/test_google_model_image_url_input.yaml +671 -0
  18. pydantic_ai-0.2.5/tests/models/cassettes/test_google/test_google_model_instructions.yaml +67 -0
  19. pydantic_ai-0.2.5/tests/models/cassettes/test_google/test_google_model_iter_stream.yaml +262 -0
  20. pydantic_ai-0.2.5/tests/models/cassettes/test_google/test_google_model_max_tokens.yaml +67 -0
  21. pydantic_ai-0.2.5/tests/models/cassettes/test_google/test_google_model_multiple_documents_in_history.yaml +82 -0
  22. pydantic_ai-0.2.5/tests/models/cassettes/test_google/test_google_model_retry.yaml +172 -0
  23. pydantic_ai-0.2.5/tests/models/cassettes/test_google/test_google_model_safety_settings.yaml +71 -0
  24. pydantic_ai-0.2.5/tests/models/cassettes/test_google/test_google_model_stream.yaml +58 -0
  25. pydantic_ai-0.2.5/tests/models/cassettes/test_google/test_google_model_structured_response.yaml +238 -0
  26. pydantic_ai-0.2.5/tests/models/cassettes/test_google/test_google_model_text_as_binary_content_input.yaml +70 -0
  27. pydantic_ai-0.2.5/tests/models/cassettes/test_google/test_google_model_text_document_url_input.yaml +130 -0
  28. pydantic_ai-0.2.5/tests/models/cassettes/test_google/test_google_model_thinking_config.yaml +66 -0
  29. pydantic_ai-0.2.5/tests/models/cassettes/test_google/test_google_model_top_p.yaml +68 -0
  30. pydantic_ai-0.2.5/tests/models/cassettes/test_google/test_google_model_vertex_provider.yaml +112 -0
  31. pydantic_ai-0.2.5/tests/models/cassettes/test_google/test_google_model_video_as_binary_content_input.yaml +81 -0
  32. pydantic_ai-0.2.5/tests/models/cassettes/test_google/test_google_model_video_url_input.yaml +11178 -0
  33. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/test_anthropic.py +13 -2
  34. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/test_fallback.py +3 -3
  35. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/test_gemini.py +2 -3
  36. pydantic_ai-0.2.5/tests/models/test_google.py +509 -0
  37. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/test_groq.py +12 -1
  38. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/test_instrumented.py +30 -12
  39. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/test_mistral.py +19 -0
  40. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/test_openai.py +65 -4
  41. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/test_openai_responses.py +1 -1
  42. pydantic_ai-0.2.5/tests/providers/cassettes/test_openrouter/test_openrouter_with_google_model.yaml +160 -0
  43. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/providers/test_google_vertex.py +4 -4
  44. pydantic_ai-0.2.5/tests/providers/test_openrouter.py +67 -0
  45. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/providers/test_provider_names.py +3 -1
  46. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/test_a2a.py +4 -4
  47. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/test_agent.py +4 -2
  48. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/test_cli.py +73 -48
  49. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/test_examples.py +17 -15
  50. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/test_logfire.py +109 -2
  51. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/test_mcp.py +19 -0
  52. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/test_messages.py +30 -23
  53. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/test_settings.py +1 -1
  54. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/test_tools.py +3 -3
  55. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/test_utils.py +1 -1
  56. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/LICENSE +0 -0
  57. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/README.md +0 -0
  58. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/__init__.py +0 -0
  59. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/assets/dummy.pdf +0 -0
  60. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/assets/kiwi.png +0 -0
  61. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/assets/marcelo.mp3 +0 -0
  62. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/assets/small_video.mp4 +0 -0
  63. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/cassettes/test_mcp/test_agent_with_stdio_server.yaml +0 -0
  64. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/cassettes/test_mcp/test_tool_returning_dict.yaml +0 -0
  65. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/cassettes/test_mcp/test_tool_returning_error.yaml +0 -0
  66. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/cassettes/test_mcp/test_tool_returning_image.yaml +0 -0
  67. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/cassettes/test_mcp/test_tool_returning_image_resource.yaml +0 -0
  68. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/cassettes/test_mcp/test_tool_returning_multiple_items.yaml +0 -0
  69. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/cassettes/test_mcp/test_tool_returning_none.yaml +0 -0
  70. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/cassettes/test_mcp/test_tool_returning_str.yaml +0 -0
  71. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/cassettes/test_mcp/test_tool_returning_text_resource.yaml +0 -0
  72. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/cassettes/test_settings/test_stop_settings[anthropic].yaml +0 -0
  73. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/cassettes/test_settings/test_stop_settings[bedrock].yaml +0 -0
  74. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/cassettes/test_settings/test_stop_settings[cohere].yaml +0 -0
  75. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/cassettes/test_settings/test_stop_settings[gemini].yaml +0 -0
  76. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/cassettes/test_settings/test_stop_settings[groq].yaml +0 -0
  77. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/cassettes/test_settings/test_stop_settings[mistral].yaml +0 -0
  78. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/cassettes/test_settings/test_stop_settings[openai].yaml +0 -0
  79. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/evals/__init__.py +0 -0
  80. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/evals/test_evaluator_context.py +0 -0
  81. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/evals/test_evaluator_spec.py +0 -0
  82. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/evals/test_llm_as_a_judge.py +0 -0
  83. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/evals/test_otel.py +0 -0
  84. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/evals/test_reporting.py +0 -0
  85. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/evals/test_reports.py +0 -0
  86. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/evals/utils.py +0 -0
  87. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/example_modules/README.md +0 -0
  88. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/example_modules/bank_database.py +0 -0
  89. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/example_modules/fake_database.py +0 -0
  90. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/example_modules/weather_service.py +0 -0
  91. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/fasta2a/__init__.py +0 -0
  92. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/graph/__init__.py +0 -0
  93. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/graph/test_file_persistence.py +0 -0
  94. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/graph/test_persistence.py +0 -0
  95. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/graph/test_state.py +0 -0
  96. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/graph/test_utils.py +0 -0
  97. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/import_examples.py +0 -0
  98. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/json_body_serializer.py +0 -0
  99. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/mcp_server.py +0 -0
  100. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/__init__.py +0 -0
  101. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_anthropic/test_anthropic_model_instructions.yaml +0 -0
  102. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_anthropic/test_document_binary_content_input.yaml +0 -0
  103. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_anthropic/test_document_url_input.yaml +0 -0
  104. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_anthropic/test_extra_headers.yaml +0 -0
  105. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_anthropic/test_image_as_binary_content_tool_response.yaml +0 -0
  106. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_anthropic/test_image_url_input.yaml +0 -0
  107. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_anthropic/test_image_url_input_invalid_mime_type.yaml +0 -0
  108. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_anthropic/test_multiple_parallel_tool_calls.yaml +0 -0
  109. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_anthropic/test_text_document_url_input.yaml +0 -0
  110. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_bedrock/test_bedrock_empty_system_prompt.yaml +0 -0
  111. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_bedrock/test_bedrock_model.yaml +0 -0
  112. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_bedrock/test_bedrock_model_anthropic_model_without_tools.yaml +0 -0
  113. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_bedrock/test_bedrock_model_guardrail_config.yaml +0 -0
  114. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_bedrock/test_bedrock_model_instructions.yaml +0 -0
  115. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_bedrock/test_bedrock_model_iter_stream.yaml +0 -0
  116. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_bedrock/test_bedrock_model_max_tokens.yaml +0 -0
  117. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_bedrock/test_bedrock_model_other_parameters.yaml +0 -0
  118. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_bedrock/test_bedrock_model_performance_config.yaml +0 -0
  119. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_bedrock/test_bedrock_model_retry.yaml +0 -0
  120. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_bedrock/test_bedrock_model_stream.yaml +0 -0
  121. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_bedrock/test_bedrock_model_structured_response.yaml +0 -0
  122. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_bedrock/test_bedrock_model_top_p.yaml +0 -0
  123. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_bedrock/test_bedrock_multiple_documents_in_history.yaml +0 -0
  124. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_bedrock/test_document_url_input.yaml +0 -0
  125. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_bedrock/test_image_as_binary_content_input.yaml +0 -0
  126. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_bedrock/test_image_url_input.yaml +0 -0
  127. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_bedrock/test_text_as_binary_content_input.yaml +0 -0
  128. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_bedrock/test_text_document_url_input.yaml +0 -0
  129. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_bedrock/test_video_as_binary_content_input.yaml +0 -0
  130. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_bedrock/test_video_url_input.yaml +0 -0
  131. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_cohere/test_cohere_model_instructions.yaml +0 -0
  132. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_cohere/test_request_simple_success_with_vcr.yaml +0 -0
  133. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_gemini/test_document_url_input.yaml +0 -0
  134. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_gemini/test_gemini_additional_properties_is_false.yaml +0 -0
  135. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_gemini/test_gemini_additional_properties_is_true.yaml +0 -0
  136. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_gemini/test_gemini_drop_exclusive_maximum.yaml +0 -0
  137. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_gemini/test_gemini_exclusive_minimum_and_maximum.yaml +0 -0
  138. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_gemini/test_gemini_model_instructions.yaml +0 -0
  139. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_gemini/test_image_as_binary_content_input.yaml +0 -0
  140. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_gemini/test_image_as_binary_content_tool_response.yaml +0 -0
  141. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_gemini/test_image_url_input.yaml +0 -0
  142. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_gemini/test_video_as_binary_content_input.yaml +0 -0
  143. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_gemini/test_video_url_input.yaml +0 -0
  144. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_groq/test_extra_headers.yaml +0 -0
  145. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_groq/test_groq_model_instructions.yaml +0 -0
  146. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_groq/test_image_as_binary_content_input.yaml +0 -0
  147. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_groq/test_image_as_binary_content_tool_response.yaml +0 -0
  148. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_groq/test_image_url_input.yaml +0 -0
  149. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_mistral/test_image_as_binary_content_tool_response.yaml +0 -0
  150. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_mistral/test_mistral_model_instructions.yaml +0 -0
  151. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_openai/test_audio_as_binary_content_input.yaml +0 -0
  152. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_openai/test_document_as_binary_content_input.yaml +0 -0
  153. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_openai/test_document_url_input.yaml +0 -0
  154. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_openai/test_extra_headers.yaml +0 -0
  155. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_openai/test_image_as_binary_content_input.yaml +0 -0
  156. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_openai/test_image_as_binary_content_tool_response.yaml +0 -0
  157. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_openai/test_image_url_tool_response.yaml +0 -0
  158. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_openai/test_max_completion_tokens[gpt-4.5-preview].yaml +0 -0
  159. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_openai/test_max_completion_tokens[gpt-4o-mini].yaml +0 -0
  160. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_openai/test_max_completion_tokens[o3-mini].yaml +0 -0
  161. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_openai/test_multiple_agent_tool_calls.yaml +0 -0
  162. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_openai/test_openai_audio_url_input.yaml +0 -0
  163. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_openai/test_openai_instructions.yaml +0 -0
  164. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_openai/test_openai_instructions_with_tool_calls_keep_instructions.yaml +0 -0
  165. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_openai/test_openai_model_without_system_prompt.yaml +0 -0
  166. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_openai/test_openai_o1_mini_system_role[developer].yaml +0 -0
  167. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_openai/test_openai_o1_mini_system_role[system].yaml +0 -0
  168. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_openai/test_user_id.yaml +0 -0
  169. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_openai_responses/test_audio_as_binary_content_input.yaml +0 -0
  170. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_openai_responses/test_image_as_binary_content_input.yaml +0 -0
  171. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_openai_responses/test_image_as_binary_content_tool_response.yaml +0 -0
  172. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_openai_responses/test_openai_responses_document_as_binary_content_input.yaml +0 -0
  173. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_openai_responses/test_openai_responses_document_url_input.yaml +0 -0
  174. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_openai_responses/test_openai_responses_image_url_input.yaml +0 -0
  175. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_openai_responses/test_openai_responses_model_builtin_tools.yaml +0 -0
  176. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_openai_responses/test_openai_responses_model_http_error.yaml +0 -0
  177. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_openai_responses/test_openai_responses_model_instructions.yaml +0 -0
  178. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_openai_responses/test_openai_responses_model_retry.yaml +0 -0
  179. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_openai_responses/test_openai_responses_model_simple_response.yaml +0 -0
  180. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_openai_responses/test_openai_responses_model_simple_response_with_tool_call.yaml +0 -0
  181. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_openai_responses/test_openai_responses_output_type.yaml +0 -0
  182. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_openai_responses/test_openai_responses_reasoning_effort.yaml +0 -0
  183. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_openai_responses/test_openai_responses_reasoning_generate_summary.yaml +0 -0
  184. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_openai_responses/test_openai_responses_stream.yaml +0 -0
  185. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_openai_responses/test_openai_responses_system_prompt.yaml +0 -0
  186. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/cassettes/test_openai_responses/test_openai_responses_text_document_url_input.yaml +0 -0
  187. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/mock_async_stream.py +0 -0
  188. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/test_bedrock.py +0 -0
  189. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/test_cohere.py +0 -0
  190. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/test_model.py +0 -0
  191. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/test_model_function.py +0 -0
  192. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/test_model_names.py +0 -0
  193. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/test_model_request_parameters.py +0 -0
  194. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/models/test_model_test.py +0 -0
  195. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/providers/__init__.py +0 -0
  196. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/providers/cassettes/test_azure/test_azure_provider_call.yaml +0 -0
  197. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/providers/cassettes/test_google_vertex/test_vertexai_provider.yaml +0 -0
  198. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/providers/test_anthropic.py +0 -0
  199. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/providers/test_azure.py +0 -0
  200. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/providers/test_bedrock.py +0 -0
  201. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/providers/test_cohere.py +0 -0
  202. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/providers/test_deepseek.py +0 -0
  203. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/providers/test_google_gla.py +0 -0
  204. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/providers/test_groq.py +0 -0
  205. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/providers/test_mistral.py +0 -0
  206. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/providers/test_openai.py +0 -0
  207. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/test_deps.py +0 -0
  208. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/test_direct.py +0 -0
  209. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/test_format_as_xml.py +0 -0
  210. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/test_json_body_serializer.py +0 -0
  211. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/test_live.py +0 -0
  212. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/test_parts_manager.py +0 -0
  213. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/test_streaming.py +0 -0
  214. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/test_usage_limits.py +0 -0
  215. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/typed_agent.py +0 -0
  216. {pydantic_ai-0.2.3 → pydantic_ai-0.2.5}/tests/typed_graph.py +0 -0
@@ -17,3 +17,5 @@ examples/pydantic_ai_examples/.chat_app_messages.sqlite
17
17
  /docs-site/.wrangler/
18
18
  /CLAUDE.md
19
19
  node_modules/
20
+ **.idea/
21
+ .coverage*
@@ -63,6 +63,10 @@ test: ## Run tests and collect coverage data
63
63
  uv run coverage run -m pytest
64
64
  @uv run coverage report
65
65
 
66
+ .PHONY: test-fast
67
+ test-fast: ## Same as test except no coverage. ~1/4th the time depending on hardware.
68
+ uv run pytest -n auto --dist=loadgroup
69
+
66
70
  .PHONY: test-all-python
67
71
  test-all-python: ## Run tests on Python 3.9 to 3.13
68
72
  UV_PROJECT_ENVIRONMENT=.venv39 uv run --python 3.9 --all-extras --all-packages coverage run -p -m pytest
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pydantic-ai
3
- Version: 0.2.3
3
+ Version: 0.2.5
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,9 +28,9 @@ 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[a2a,anthropic,bedrock,cli,cohere,evals,groq,mcp,mistral,openai,vertexai]==0.2.3
31
+ Requires-Dist: pydantic-ai-slim[a2a,anthropic,bedrock,cli,cohere,evals,google,groq,mcp,mistral,openai,vertexai]==0.2.5
32
32
  Provides-Extra: examples
33
- Requires-Dist: pydantic-ai-examples==0.2.3; extra == 'examples'
33
+ Requires-Dist: pydantic-ai-examples==0.2.5; extra == 'examples'
34
34
  Provides-Extra: logfire
35
35
  Requires-Dist: logfire>=3.11.0; extra == 'logfire'
36
36
  Description-Content-Type: text/markdown
@@ -46,7 +46,7 @@ requires-python = ">=3.9"
46
46
 
47
47
  [tool.hatch.metadata.hooks.uv-dynamic-versioning]
48
48
  dependencies = [
49
- "pydantic-ai-slim[openai,vertexai,groq,anthropic,mistral,cohere,bedrock,cli,mcp,evals,a2a]=={{ version }}",
49
+ "pydantic-ai-slim[openai,vertexai,google,groq,anthropic,mistral,cohere,bedrock,cli,mcp,evals,a2a]=={{ version }}",
50
50
  ]
51
51
 
52
52
  [tool.hatch.metadata.hooks.uv-dynamic-versioning.optional-dependencies]
@@ -60,7 +60,7 @@ Documentation = "https://ai.pydantic.dev"
60
60
  Changelog = "https://github.com/pydantic/pydantic-ai/releases"
61
61
 
62
62
  [project.scripts]
63
- pai = "pydantic_ai._cli:cli_exit" # TODO remove this when clai has been out for a while
63
+ pai = "pydantic_ai._cli:cli_exit" # TODO remove this when clai has been out for a while
64
64
 
65
65
  [tool.uv.sources]
66
66
  pydantic-ai-slim = { workspace = true }
@@ -170,7 +170,8 @@ include = [
170
170
  "examples",
171
171
  "clai",
172
172
  ]
173
- venvPath = ".venv"
173
+ venvPath = '.'
174
+ venv = ".venv"
174
175
  # see https://github.com/microsoft/pyright/issues/7771 - we don't want to error on decorated functions in tests
175
176
  # which are not otherwise used
176
177
  executionEnvironments = [
@@ -65,7 +65,7 @@ class TestEnv:
65
65
  if value is None:
66
66
  os.environ.pop(name, None)
67
67
  else:
68
- os.environ[name] = value
68
+ os.environ[name] = value # pragma: lax no cover
69
69
 
70
70
 
71
71
  @pytest.fixture
@@ -101,7 +101,7 @@ async def client_with_handler() -> AsyncIterator[ClientWithHandler]:
101
101
  try:
102
102
  yield create_client
103
103
  finally:
104
- if client:
104
+ if client: # pragma: no branch
105
105
  await client.aclose()
106
106
 
107
107
 
@@ -276,6 +276,11 @@ def mistral_api_key() -> str:
276
276
  return os.getenv('MISTRAL_API_KEY', 'mock-api-key')
277
277
 
278
278
 
279
+ @pytest.fixture(scope='session')
280
+ def openrouter_api_key() -> str:
281
+ return os.getenv('OPENROUTER_API_KEY', 'mock-api-key')
282
+
283
+
279
284
  @pytest.fixture(scope='session')
280
285
  def bedrock_provider():
281
286
  try:
@@ -291,7 +296,7 @@ def bedrock_provider():
291
296
  )
292
297
  yield BedrockProvider(bedrock_client=bedrock_client)
293
298
  bedrock_client.close()
294
- except ImportError:
299
+ except ImportError: # pragma: lax no cover
295
300
  pytest.skip('boto3 is not installed')
296
301
 
297
302
 
@@ -39,9 +39,9 @@ pytestmark = [pytest.mark.skipif(not imports_successful(), reason='pydantic-eval
39
39
 
40
40
 
41
41
  if sys.version_info < (3, 11):
42
- from exceptiongroup import ExceptionGroup
42
+ from exceptiongroup import ExceptionGroup # pragma: lax no cover
43
43
  else:
44
- ExceptionGroup = ExceptionGroup
44
+ ExceptionGroup = ExceptionGroup # pragma: lax no cover
45
45
 
46
46
 
47
47
  @pytest.fixture(autouse=True)
@@ -636,7 +636,7 @@ async def test_from_text_failure():
636
636
  with pytest.raises(ExceptionGroup) as exc_info:
637
637
  Dataset[TaskInput, TaskOutput, TaskMetadata].from_text(json.dumps(dataset_dict))
638
638
  if sys.version_info >= (3, 10):
639
- assert exc_info.value == HasRepr(
639
+ assert exc_info.value == HasRepr( # pragma: lax no cover
640
640
  repr(
641
641
  ExceptionGroup(
642
642
  '2 error(s) loading evaluators from registry',
@@ -652,7 +652,7 @@ async def test_from_text_failure():
652
652
  )
653
653
  )
654
654
  else:
655
- assert exc_info.value == HasRepr(
655
+ assert exc_info.value == HasRepr( # pragma: lax no cover
656
656
  repr(
657
657
  ExceptionGroup(
658
658
  '2 error(s) loading evaluators from registry',
@@ -86,7 +86,7 @@ def test_strict_abc_meta():
86
86
  assert 'evaluate' in str(exc_info.value)
87
87
 
88
88
 
89
- if TYPE_CHECKING or imports_successful():
89
+ if TYPE_CHECKING or imports_successful(): # pragma: no branch
90
90
 
91
91
  @dataclass
92
92
  class SimpleEvaluator(Evaluator[Any, Any, Any]):
@@ -172,10 +172,11 @@ async def test_evaluator_async():
172
172
  assert result is True
173
173
 
174
174
 
175
- async def test_evaluator_name():
175
+ async def test_evaluation_name():
176
176
  """Test evaluator name method."""
177
177
  evaluator = SimpleEvaluator()
178
- assert evaluator.name() == 'SimpleEvaluator'
178
+ assert evaluator.get_serialization_name() == 'SimpleEvaluator'
179
+ assert evaluator.get_default_evaluation_name() == 'SimpleEvaluator'
179
180
 
180
181
 
181
182
  async def test_evaluator_serialization():
@@ -5,6 +5,7 @@ from typing import TYPE_CHECKING, Any
5
5
 
6
6
  import pytest
7
7
  from inline_snapshot import snapshot
8
+ from pydantic_core import to_jsonable_python
8
9
  from pytest_mock import MockerFixture
9
10
 
10
11
  from pydantic_ai.settings import ModelSettings
@@ -25,6 +26,7 @@ with try_import() as imports_successful:
25
26
  IsInstance,
26
27
  LLMJudge,
27
28
  MaxDuration,
29
+ OutputConfig,
28
30
  Python,
29
31
  )
30
32
  from pydantic_evals.otel._context_in_memory_span_exporter import context_subtree
@@ -43,7 +45,7 @@ if TYPE_CHECKING or imports_successful():
43
45
  self.inputs = inputs
44
46
  self.duration = duration
45
47
  else:
46
- MockContext = object
48
+ MockContext = object # pragma: lax no cover
47
49
 
48
50
 
49
51
  async def test_equals():
@@ -194,6 +196,7 @@ async def test_llm_judge_evaluator(mocker: MockerFixture):
194
196
  """Test LLMJudge evaluator."""
195
197
  # Create a mock GradingOutput
196
198
  mock_grading_output = mocker.MagicMock()
199
+ mock_grading_output.score = 1.0
197
200
  mock_grading_output.pass_ = True
198
201
  mock_grading_output.reason = 'Test passed'
199
202
 
@@ -219,31 +222,42 @@ async def test_llm_judge_evaluator(mocker: MockerFixture):
219
222
 
220
223
  # Test without input
221
224
  evaluator = LLMJudge(rubric='Content contains a greeting')
222
- result = await evaluator.evaluate(ctx)
223
- assert isinstance(result, EvaluationReason)
224
- assert result.value is True
225
- assert result.reason == 'Test passed'
225
+ assert to_jsonable_python(await evaluator.evaluate(ctx)) == snapshot(
226
+ {'LLMJudge': {'value': True, 'reason': 'Test passed'}}
227
+ )
226
228
 
227
229
  mock_judge_output.assert_called_once_with('Hello world', 'Content contains a greeting', None, None)
228
230
 
229
231
  # Test with input
230
232
  evaluator = LLMJudge(rubric='Output contains input', include_input=True, model='openai:gpt-4o')
231
- result = await evaluator.evaluate(ctx)
232
- assert isinstance(result, EvaluationReason)
233
- assert result.value is True
234
- assert result.reason == 'Test passed'
233
+ assert to_jsonable_python(await evaluator.evaluate(ctx)) == snapshot(
234
+ {'LLMJudge': {'value': True, 'reason': 'Test passed'}}
235
+ )
235
236
 
236
237
  mock_judge_input_output.assert_called_once_with(
237
238
  {'prompt': 'Hello'}, 'Hello world', 'Output contains input', 'openai:gpt-4o', None
238
239
  )
239
240
 
240
241
  # Test with failing result
242
+ mock_grading_output.score = 0.0
241
243
  mock_grading_output.pass_ = False
242
244
  mock_grading_output.reason = 'Test failed'
243
- result = await evaluator.evaluate(ctx)
244
- assert isinstance(result, EvaluationReason)
245
- assert result.value is False
246
- assert result.reason == 'Test failed'
245
+ assert to_jsonable_python(await evaluator.evaluate(ctx)) == snapshot(
246
+ {'LLMJudge': {'value': False, 'reason': 'Test failed'}}
247
+ )
248
+
249
+ # Test with overridden configs
250
+ evaluator = LLMJudge(rubric='Mock rubric', assertion=False)
251
+ assert to_jsonable_python(await evaluator.evaluate(ctx)) == snapshot({})
252
+
253
+ evaluator = LLMJudge(
254
+ rubric='Mock rubric',
255
+ score=OutputConfig(evaluation_name='my_score', include_reason=True),
256
+ assertion=OutputConfig(evaluation_name='my_assertion'),
257
+ )
258
+ assert to_jsonable_python(await evaluator.evaluate(ctx)) == snapshot(
259
+ {'my_assertion': False, 'my_score': {'reason': 'Test failed', 'value': 0.0}}
260
+ )
247
261
 
248
262
 
249
263
  @pytest.mark.anyio
@@ -275,9 +289,9 @@ async def test_llm_judge_evaluator_with_model_settings(mocker: MockerFixture):
275
289
 
276
290
  # Test without input, with custom model_settings
277
291
  evaluator_no_input = LLMJudge(rubric='Greeting with custom settings', model_settings=custom_model_settings)
278
- result_no_input = await evaluator_no_input.evaluate(ctx)
279
- assert result_no_input.value is True
280
- assert result_no_input.reason == 'Test passed with settings'
292
+ assert to_jsonable_python(await evaluator_no_input.evaluate(ctx)) == snapshot(
293
+ {'LLMJudge': {'value': True, 'reason': 'Test passed with settings'}}
294
+ )
281
295
  mock_judge_output.assert_called_once_with(
282
296
  'Hello world custom settings', 'Greeting with custom settings', None, custom_model_settings
283
297
  )
@@ -289,9 +303,9 @@ async def test_llm_judge_evaluator_with_model_settings(mocker: MockerFixture):
289
303
  model='openai:gpt-3.5-turbo',
290
304
  model_settings=custom_model_settings,
291
305
  )
292
- result_with_input = await evaluator_with_input.evaluate(ctx)
293
- assert result_with_input.value is True
294
- assert result_with_input.reason == 'Test passed with settings'
306
+ assert to_jsonable_python(await evaluator_with_input.evaluate(ctx)) == snapshot(
307
+ {'LLMJudge': {'value': True, 'reason': 'Test passed with settings'}}
308
+ )
295
309
  mock_judge_input_output.assert_called_once_with(
296
310
  {'prompt': 'Hello Custom'},
297
311
  'Hello world custom settings',
@@ -6,6 +6,7 @@ from typing import Any, cast
6
6
  import pytest
7
7
  from inline_snapshot import snapshot
8
8
  from pydantic import BaseModel, TypeAdapter
9
+ from pydantic_core import to_jsonable_python
9
10
 
10
11
  from pydantic_ai.messages import ModelMessage, ModelResponse
11
12
  from pydantic_ai.models import Model, ModelRequestParameters
@@ -207,12 +208,6 @@ async def test_is_instance_evaluator():
207
208
  assert result.value is False
208
209
 
209
210
 
210
- async def test_llm_judge_evaluator():
211
- """Test the LLMJudge evaluator."""
212
- # We can't easily test this without mocking the LLM, so we'll just check that it's importable
213
- assert LLMJudge
214
-
215
-
216
211
  async def test_custom_evaluator(test_context: EvaluatorContext[TaskInput, TaskOutput, TaskMetadata]):
217
212
  """Test a custom evaluator."""
218
213
 
@@ -232,9 +227,41 @@ async def test_custom_evaluator(test_context: EvaluatorContext[TaskInput, TaskOu
232
227
 
233
228
  evaluator = CustomEvaluator()
234
229
  result = evaluator.evaluate(test_context)
235
- assert isinstance(result, dict)
236
- assert result['is_correct'] is True
237
- assert result['difficulty'] == 'easy'
230
+ assert result == snapshot({'difficulty': 'easy', 'is_correct': True})
231
+
232
+
233
+ async def test_custom_evaluator_name(test_context: EvaluatorContext[TaskInput, TaskOutput, TaskMetadata]):
234
+ @dataclass
235
+ class CustomNameFieldEvaluator(Evaluator[TaskInput, TaskOutput, TaskMetadata]):
236
+ result: int
237
+ evaluation_name: str
238
+
239
+ def evaluate(self, ctx: EvaluatorContext[TaskInput, TaskOutput, TaskMetadata]) -> EvaluatorOutput:
240
+ return self.result
241
+
242
+ evaluator = CustomNameFieldEvaluator(result=123, evaluation_name='abc')
243
+
244
+ assert to_jsonable_python(await run_evaluator(evaluator, test_context)) == snapshot(
245
+ [{'name': 'abc', 'reason': None, 'source': {'evaluation_name': 'abc', 'result': 123}, 'value': 123}]
246
+ )
247
+
248
+ @dataclass
249
+ class CustomNamePropertyEvaluator(Evaluator[TaskInput, TaskOutput, TaskMetadata]):
250
+ result: int
251
+ my_name: str
252
+
253
+ @property
254
+ def evaluation_name(self) -> str:
255
+ return f'hello {self.my_name}'
256
+
257
+ def evaluate(self, ctx: EvaluatorContext[TaskInput, TaskOutput, TaskMetadata]) -> EvaluatorOutput:
258
+ return self.result
259
+
260
+ evaluator = CustomNamePropertyEvaluator(result=123, my_name='marcelo')
261
+
262
+ assert to_jsonable_python(await run_evaluator(evaluator, test_context)) == snapshot(
263
+ [{'name': 'hello marcelo', 'reason': None, 'source': {'my_name': 'marcelo', 'result': 123}, 'value': 123}]
264
+ )
238
265
 
239
266
 
240
267
  async def test_evaluator_error_handling(test_context: EvaluatorContext[TaskInput, TaskOutput, TaskMetadata]):
@@ -21,8 +21,8 @@ pytestmark = [pytest.mark.skipif(not imports_successful(), reason='pydantic-eval
21
21
  [
22
22
  (0, snapshot('0')),
23
23
  (0.0, snapshot('0.000')),
24
- (17348, snapshot('17348')),
25
- (-17348, snapshot('-17348')),
24
+ (17348, snapshot('17,348')),
25
+ (-17348, snapshot('-17,348')),
26
26
  (17347.0, snapshot('17,347.0')),
27
27
  (-17347.0, snapshot('-17,347.0')),
28
28
  (0.1234, snapshot('0.123')),
@@ -11,9 +11,9 @@ from dirty_equals import HasRepr
11
11
  from ..conftest import try_import
12
12
 
13
13
  if sys.version_info < (3, 11):
14
- from exceptiongroup import ExceptionGroup
14
+ from exceptiongroup import ExceptionGroup # pragma: lax no cover
15
15
  else:
16
- ExceptionGroup = ExceptionGroup
16
+ ExceptionGroup = ExceptionGroup # pragma: lax no cover
17
17
 
18
18
 
19
19
  with try_import() as imports_successful:
@@ -410,7 +410,7 @@ async def test_next(mock_snapshot_id: object):
410
410
  @dataclass
411
411
  class Bar(BaseNode):
412
412
  async def run(self, ctx: GraphRunContext) -> Foo:
413
- return Foo()
413
+ return Foo() # pragma: no cover
414
414
 
415
415
  g = Graph(nodes=(Foo, Bar))
416
416
  assert g.name is None
@@ -259,7 +259,7 @@ def httpx_with_handler() -> Iterator[HttpxWithHandler]:
259
259
  try:
260
260
  yield create_client
261
261
  finally:
262
- if client:
262
+ if client: # pragma: no branch
263
263
  client.close()
264
264
 
265
265
 
@@ -0,0 +1,67 @@
1
+ interactions:
2
+ - request:
3
+ headers:
4
+ accept:
5
+ - '*/*'
6
+ accept-encoding:
7
+ - gzip, deflate
8
+ connection:
9
+ - keep-alive
10
+ content-length:
11
+ - '169'
12
+ content-type:
13
+ - application/json
14
+ host:
15
+ - generativelanguage.googleapis.com
16
+ method: POST
17
+ parsed_body:
18
+ contents:
19
+ - parts:
20
+ - text: Hello!
21
+ role: user
22
+ generationConfig: {}
23
+ systemInstruction:
24
+ parts:
25
+ - text: You are a chatbot.
26
+ role: user
27
+ uri: https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent
28
+ response:
29
+ headers:
30
+ alt-svc:
31
+ - h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
32
+ content-length:
33
+ - '644'
34
+ content-type:
35
+ - application/json; charset=UTF-8
36
+ server-timing:
37
+ - gfet4t7; dur=322
38
+ transfer-encoding:
39
+ - chunked
40
+ vary:
41
+ - Origin
42
+ - X-Origin
43
+ - Referer
44
+ parsed_body:
45
+ candidates:
46
+ - avgLogprobs: -0.0009223055941137401
47
+ content:
48
+ parts:
49
+ - text: |
50
+ Hello there! How can I help you today?
51
+ role: model
52
+ finishReason: STOP
53
+ modelVersion: gemini-1.5-flash
54
+ usageMetadata:
55
+ candidatesTokenCount: 11
56
+ candidatesTokensDetails:
57
+ - modality: TEXT
58
+ tokenCount: 11
59
+ promptTokenCount: 7
60
+ promptTokensDetails:
61
+ - modality: TEXT
62
+ tokenCount: 7
63
+ totalTokenCount: 18
64
+ status:
65
+ code: 200
66
+ message: OK
67
+ version: 1