pydantic-ai 0.1.1__tar.gz → 0.1.3__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 (168) hide show
  1. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/Makefile +1 -1
  2. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/PKG-INFO +3 -3
  3. pydantic_ai-0.1.3/tests/models/cassettes/test_bedrock/test_bedrock_multiple_documents_in_history.yaml +52 -0
  4. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/test_bedrock.py +23 -2
  5. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/test_instrumented.py +44 -0
  6. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/test_openai.py +54 -14
  7. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/test_agent.py +66 -2
  8. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/test_mcp.py +10 -0
  9. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/test_tools.py +14 -0
  10. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/.gitignore +0 -0
  11. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/LICENSE +0 -0
  12. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/README.md +0 -0
  13. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/pyproject.toml +0 -0
  14. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/__init__.py +0 -0
  15. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/assets/dummy.pdf +0 -0
  16. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/assets/kiwi.png +0 -0
  17. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/assets/marcelo.mp3 +0 -0
  18. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/assets/small_video.mp4 +0 -0
  19. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/cassettes/test_mcp/test_agent_with_stdio_server.yaml +0 -0
  20. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/cassettes/test_settings/test_stop_settings[anthropic].yaml +0 -0
  21. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/cassettes/test_settings/test_stop_settings[bedrock].yaml +0 -0
  22. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/cassettes/test_settings/test_stop_settings[cohere].yaml +0 -0
  23. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/cassettes/test_settings/test_stop_settings[gemini].yaml +0 -0
  24. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/cassettes/test_settings/test_stop_settings[groq].yaml +0 -0
  25. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/cassettes/test_settings/test_stop_settings[mistral].yaml +0 -0
  26. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/cassettes/test_settings/test_stop_settings[openai].yaml +0 -0
  27. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/conftest.py +0 -0
  28. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/evals/__init__.py +0 -0
  29. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/evals/test_dataset.py +0 -0
  30. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/evals/test_evaluator_base.py +0 -0
  31. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/evals/test_evaluator_common.py +0 -0
  32. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/evals/test_evaluator_context.py +0 -0
  33. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/evals/test_evaluator_spec.py +0 -0
  34. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/evals/test_evaluators.py +0 -0
  35. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/evals/test_llm_as_a_judge.py +0 -0
  36. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/evals/test_otel.py +0 -0
  37. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/evals/test_render_numbers.py +0 -0
  38. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/evals/test_reporting.py +0 -0
  39. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/evals/test_reports.py +0 -0
  40. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/evals/test_utils.py +0 -0
  41. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/evals/utils.py +0 -0
  42. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/example_modules/README.md +0 -0
  43. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/example_modules/bank_database.py +0 -0
  44. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/example_modules/fake_database.py +0 -0
  45. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/example_modules/weather_service.py +0 -0
  46. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/graph/__init__.py +0 -0
  47. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/graph/test_file_persistence.py +0 -0
  48. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/graph/test_graph.py +0 -0
  49. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/graph/test_mermaid.py +0 -0
  50. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/graph/test_persistence.py +0 -0
  51. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/graph/test_state.py +0 -0
  52. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/graph/test_utils.py +0 -0
  53. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/import_examples.py +0 -0
  54. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/json_body_serializer.py +0 -0
  55. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/mcp_server.py +0 -0
  56. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/__init__.py +0 -0
  57. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_anthropic/test_anthropic_model_instructions.yaml +0 -0
  58. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_anthropic/test_document_binary_content_input.yaml +0 -0
  59. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_anthropic/test_document_url_input.yaml +0 -0
  60. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_anthropic/test_image_url_input.yaml +0 -0
  61. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_anthropic/test_image_url_input_invalid_mime_type.yaml +0 -0
  62. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_anthropic/test_multiple_parallel_tool_calls.yaml +0 -0
  63. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_anthropic/test_text_document_url_input.yaml +0 -0
  64. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_bedrock/test_bedrock_empty_system_prompt.yaml +0 -0
  65. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_bedrock/test_bedrock_model.yaml +0 -0
  66. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_bedrock/test_bedrock_model_anthropic_model_without_tools.yaml +0 -0
  67. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_bedrock/test_bedrock_model_guardrail_config.yaml +0 -0
  68. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_bedrock/test_bedrock_model_instructions.yaml +0 -0
  69. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_bedrock/test_bedrock_model_iter_stream.yaml +0 -0
  70. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_bedrock/test_bedrock_model_max_tokens.yaml +0 -0
  71. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_bedrock/test_bedrock_model_other_parameters.yaml +0 -0
  72. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_bedrock/test_bedrock_model_performance_config.yaml +0 -0
  73. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_bedrock/test_bedrock_model_retry.yaml +0 -0
  74. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_bedrock/test_bedrock_model_stream.yaml +0 -0
  75. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_bedrock/test_bedrock_model_structured_response.yaml +0 -0
  76. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_bedrock/test_bedrock_model_top_p.yaml +0 -0
  77. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_bedrock/test_document_url_input.yaml +0 -0
  78. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_bedrock/test_image_as_binary_content_input.yaml +0 -0
  79. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_bedrock/test_image_url_input.yaml +0 -0
  80. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_bedrock/test_text_as_binary_content_input.yaml +0 -0
  81. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_bedrock/test_text_document_url_input.yaml +0 -0
  82. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_bedrock/test_video_as_binary_content_input.yaml +0 -0
  83. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_bedrock/test_video_url_input.yaml +0 -0
  84. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_cohere/test_cohere_model_instructions.yaml +0 -0
  85. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_cohere/test_request_simple_success_with_vcr.yaml +0 -0
  86. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_gemini/test_document_url_input.yaml +0 -0
  87. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_gemini/test_gemini_additional_properties_is_false.yaml +0 -0
  88. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_gemini/test_gemini_additional_properties_is_true.yaml +0 -0
  89. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_gemini/test_gemini_drop_exclusive_maximum.yaml +0 -0
  90. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_gemini/test_gemini_exclusive_minimum_and_maximum.yaml +0 -0
  91. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_gemini/test_gemini_model_instructions.yaml +0 -0
  92. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_gemini/test_image_as_binary_content_input.yaml +0 -0
  93. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_gemini/test_image_url_input.yaml +0 -0
  94. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_groq/test_groq_model_instructions.yaml +0 -0
  95. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_groq/test_image_as_binary_content_input.yaml +0 -0
  96. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_groq/test_image_url_input.yaml +0 -0
  97. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_mistral/test_mistral_model_instructions.yaml +0 -0
  98. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_openai/test_audio_as_binary_content_input.yaml +0 -0
  99. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_openai/test_document_url_input.yaml +0 -0
  100. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_openai/test_image_as_binary_content_input.yaml +0 -0
  101. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_openai/test_max_completion_tokens[gpt-4.5-preview].yaml +0 -0
  102. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_openai/test_max_completion_tokens[gpt-4o-mini].yaml +0 -0
  103. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_openai/test_max_completion_tokens[o3-mini].yaml +0 -0
  104. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_openai/test_multiple_agent_tool_calls.yaml +0 -0
  105. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_openai/test_openai_instructions.yaml +0 -0
  106. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_openai/test_openai_instructions_with_tool_calls_keep_instructions.yaml +0 -0
  107. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_openai/test_openai_model_without_system_prompt.yaml +0 -0
  108. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_openai/test_openai_o1_mini_system_role[developer].yaml +0 -0
  109. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_openai/test_openai_o1_mini_system_role[system].yaml +0 -0
  110. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_openai/test_user_id.yaml +0 -0
  111. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_openai_responses/test_audio_as_binary_content_input.yaml +0 -0
  112. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_openai_responses/test_image_as_binary_content_input.yaml +0 -0
  113. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_openai_responses/test_openai_responses_document_as_binary_content_input.yaml +0 -0
  114. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_openai_responses/test_openai_responses_document_url_input.yaml +0 -0
  115. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_openai_responses/test_openai_responses_image_url_input.yaml +0 -0
  116. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_openai_responses/test_openai_responses_model_builtin_tools.yaml +0 -0
  117. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_openai_responses/test_openai_responses_model_http_error.yaml +0 -0
  118. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_openai_responses/test_openai_responses_model_instructions.yaml +0 -0
  119. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_openai_responses/test_openai_responses_model_retry.yaml +0 -0
  120. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_openai_responses/test_openai_responses_model_simple_response.yaml +0 -0
  121. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_openai_responses/test_openai_responses_model_simple_response_with_tool_call.yaml +0 -0
  122. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_openai_responses/test_openai_responses_output_type.yaml +0 -0
  123. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_openai_responses/test_openai_responses_reasoning_effort.yaml +0 -0
  124. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_openai_responses/test_openai_responses_reasoning_generate_summary.yaml +0 -0
  125. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_openai_responses/test_openai_responses_stream.yaml +0 -0
  126. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_openai_responses/test_openai_responses_system_prompt.yaml +0 -0
  127. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/cassettes/test_openai_responses/test_openai_responses_text_document_url_input.yaml +0 -0
  128. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/mock_async_stream.py +0 -0
  129. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/test_anthropic.py +0 -0
  130. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/test_cohere.py +0 -0
  131. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/test_fallback.py +0 -0
  132. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/test_gemini.py +0 -0
  133. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/test_groq.py +0 -0
  134. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/test_mistral.py +0 -0
  135. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/test_model.py +0 -0
  136. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/test_model_function.py +0 -0
  137. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/test_model_names.py +0 -0
  138. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/test_model_test.py +0 -0
  139. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/models/test_openai_responses.py +0 -0
  140. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/providers/__init__.py +0 -0
  141. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/providers/cassettes/test_azure/test_azure_provider_call.yaml +0 -0
  142. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/providers/cassettes/test_google_vertex/test_vertexai_provider.yaml +0 -0
  143. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/providers/test_anthropic.py +0 -0
  144. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/providers/test_azure.py +0 -0
  145. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/providers/test_bedrock.py +0 -0
  146. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/providers/test_cohere.py +0 -0
  147. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/providers/test_deepseek.py +0 -0
  148. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/providers/test_google_gla.py +0 -0
  149. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/providers/test_google_vertex.py +0 -0
  150. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/providers/test_groq.py +0 -0
  151. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/providers/test_mistral.py +0 -0
  152. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/providers/test_openai.py +0 -0
  153. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/providers/test_provider_names.py +0 -0
  154. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/test_cli.py +0 -0
  155. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/test_deps.py +0 -0
  156. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/test_examples.py +0 -0
  157. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/test_format_as_xml.py +0 -0
  158. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/test_json_body_serializer.py +0 -0
  159. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/test_live.py +0 -0
  160. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/test_logfire.py +0 -0
  161. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/test_messages.py +0 -0
  162. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/test_parts_manager.py +0 -0
  163. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/test_settings.py +0 -0
  164. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/test_streaming.py +0 -0
  165. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/test_usage_limits.py +0 -0
  166. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/test_utils.py +0 -0
  167. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/typed_agent.py +0 -0
  168. {pydantic_ai-0.1.1 → pydantic_ai-0.1.3}/tests/typed_graph.py +0 -0
@@ -80,7 +80,7 @@ testcov: test ## Run tests and generate a coverage report
80
80
 
81
81
  .PHONY: test-mrp
82
82
  test-mrp: ## Build and tests of mcp-run-python
83
- cd mcp-run-python && npm run prepare
83
+ cd mcp-run-python && deno task build
84
84
  uv run --package mcp-run-python pytest mcp-run-python -v
85
85
 
86
86
  .PHONY: update-examples
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pydantic-ai
3
- Version: 0.1.1
3
+ Version: 0.1.3
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[anthropic,bedrock,cli,cohere,evals,groq,mcp,mistral,openai,vertexai]==0.1.1
31
+ Requires-Dist: pydantic-ai-slim[anthropic,bedrock,cli,cohere,evals,groq,mcp,mistral,openai,vertexai]==0.1.3
32
32
  Provides-Extra: examples
33
- Requires-Dist: pydantic-ai-examples==0.1.1; extra == 'examples'
33
+ Requires-Dist: pydantic-ai-examples==0.1.3; extra == 'examples'
34
34
  Provides-Extra: logfire
35
35
  Requires-Dist: logfire>=3.11.0; extra == 'logfire'
36
36
  Description-Content-Type: text/markdown
@@ -0,0 +1,52 @@
1
+ interactions:
2
+ - request:
3
+ body: '{"messages": [{"role": "user", "content": [{"text": "Here is a PDF document: "}, {"document": {"name": "Document
4
+ 1", "format": "pdf", "source": {"bytes": "JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0ZpbHRlci9GbGF0ZURlY29kZT4+CnN0cmVhbQp4nD2OywoCMQxF9/mKu3YRk7bptDAIDuh+oOAP+AAXgrOZ37etjmSTe3ISIljpDYGwwrKxRwrKGcsNlx1e31mt5UFTIYucMFiqcrlif1ZobP0do6g48eIPKE+ydk6aM0roJG/RegwcNhDr5tChd+z+miTJnWqoT/3oUabOToVmmvEBy5IoCgplbmRzdHJlYW0KZW5kb2JqCgozIDAgb2JqCjEzNAplbmRvYmoKCjUgMCBvYmoKPDwvTGVuZ3RoIDYgMCBSL0ZpbHRlci9GbGF0ZURlY29kZS9MZW5ndGgxIDIzMTY0Pj4Kc3RyZWFtCnic7Xx5fFvVlf+59z0tdrzIu7xFz1G8Kl7i2HEWE8vxQlI3iRM71A6ksSwrsYptKZYUE9omYStgloZhaSlMMbTsbSPLAZwEGgNlusxQ0mHa0k4Z8muhlJb8ynQoZVpi/b736nkjgWlnfn/8Pp9fpNx3zz33bPecc899T4oVHA55KIEOkUJO96DLvyQxM5WI/omIpbr3BbU/3J61FPBpItOa3f49g1948t/vI4rLIzL8dM/A/t3vn77ZSpT0LlH8e/0eV98jn3k0mSj7bchY2Q/EpdNXm4hyIIOW9g8Gr+gyrq3EeAPGVQM+t+uw5VrQ51yBcc6g6wr/DywvGAHegbE25Br0bFR/ezPGR4kq6/y+QPCnVBYl2ijka/5hjz95S8kmok8kEFl8wDG8xQtjZhRjrqgGo8kcF7+I/r98GY5TnmwPU55aRIhb9PWZNu2Nvi7mRM9/C2flx5r+itA36KeshGk0wf5MWfQ+y2bLaSOp9CdkyxE6S3dSOnXSXSyVllImbaeNTAWNg25m90T3Rd+ii+jv6IHoU+zq6GOY/yL9A70PC/5NZVRHm0G/nTz0lvIGdUe/Qma6nhbRWtrGMslFP8H7j7DhdrqDvs0+F30fWtPpasirp0ZqjD4b/YDK6Gb1sOGVuCfoNjrBjFF31EuLaQmNckf0J9HXqIi66Wv0DdjkYFPqBiqgy+k6+jLLVv4B0J30dZpmCXyn0mQ4CU0b6RIaohEapcfoByyVtRteMbwT/Wz0TTJSGpXAJi+9xWrZJv6gmhBdF/05XUrH6HtYr3hPqZeqDxsunW6I/n30Ocqgp1g8e5o9a6g23Hr2quj90W8hI4toOTyyGXp66Rp6lr5P/05/4AejB2kDdUDzCyyfaawIHv8Jz+YH+AHlZarAanfC2hDdR2FE5DidoGfgm3+l0/QGS2e57BOsl93G/sATeB9/SblHOar8i8rUR+FvOxXCR0F6kJ7Efn6RXmIGyK9i7ewzzMe+xP6eneZh/jb/k2pWr1H/op41FE2fnv5LdHP0j2SlHPokXUkH4duv0QQdpR/Sj+kP9B/0HrOwVayf3c/C7DR7m8fxJXwL9/O7+IP8m8pm5TblWbVWXa9err6o/tzwBcNNJpdp+oOHpm+f/ub0j6JPRX+E3EmC/CJqhUevQlY8SCfpZUj/Gb1KvxT5A/lr2Q72aWgJsBvYHeyb7AX2I/ZbrJLkewlfy5uh1ceH4aer+e38Dmh/Ce9T/Of8Vf47/kfFoCxRVip7lfuVsDKpnFJ+rVrUIrVCXa5uUXeoUUSm2nCxocPwiOFxw3OGd4z1xj6j3/gb09Wma83/dLbs7L9N03T/dHh6ArlrRiZdCU98lR5A3h9FDH4Aj/4QFp+mdxGFHFbAimH3atbK2tgm9il2GfOwq9n17O/Yl9k97AH2LawAa+Am2O7gjbyDu7iHX8uv57fwo3gf59/nP+Gv8DOwPEuxKw5lubJR2aFcqgxhDUHlgHItPHub8pjykvKy8qbyG+UMopalLlZD6pXq3erD6lH1R4ZPGgbxfsBw0jBl+JHhA8MHRm7MMeYZK42fMT5i/KXJaFppajfdaPoX03+Y/SyPlcFybX614NnYg4v5YzxdPcjOAJHPVErGyh2IQwd2xX9QgzKNuCSJediWwbPVNMFpdKph8AfZCaplL9BBI1dQidXTFGG/4KfV5/lF9GPWw7LVh5Uhww94AT2OanSYP81PsPV0lNfzS/i9CrE32CP0BvL9CrqDXc4C9Dg7w9awz7M6dpD+hWcqHexaqo8+wFUWxzaydwgW0FVqH33646sgW02/oLemv6omqp9DfZqkuxDRb9Br7FH6MzNE30Z1U1CNXKgyNyPfryNR9XZinx3EfsxGBRkwvkRHxYliqjOuU6+kd+g/6S3DcWTUelTSN6e96lfVX0XrouXYYdhl9Aj2XT9djB3zBrLkGYzF6DLs9HjUkmrs6nbaQX30eVS926Lh6L3Ra6L7oz76R/D+mS1jf2Zj2BGT4Kin7+H9RfoZuwn78OL/3ikw3UdT9FtmZYWsGvvhjGGf4bDhMcNRw7cNLxqXw9vX0j3I6F8im+OxAjf9iH5Lf2JmxCabllEN7F0F27togHcrz1ATyyE/9mwJ6vh6fSUBSLka3rsX+/kZ7I13UCcuo2/TK4yzLKzIDf1myGmDn3eB+iFE8Bo2AUwfqnYZ/Q7rTmKreBD6nJB0F6rWFGz6Bf0a3o5Ku5ahLjSzSyDrT/Qp6oOGldTOxhGBJ2k1Kmuz8k/w91JmofVsCfs6+HqwQ5Mon1YbfsU4LZveHF3FvcozOGOiwI/h9Mqli9heWJGMdZylDLaFaqe3wYaXiZyNnc6GdRfVr12zelVdbc2K6uVVlRXlyxxlpSXFRYVL7UsKNNvi/LzcnGxrVmZGelpqiiU5KTFhUXyc2WQ0qApntKzF3tqjhYt6wmqRfcOGcjG2u4BwzUP0hDWgWhfShLUeSaYtpHSCcveHKJ0xSucsJbNo9VRfvkxrsWvhF5vt2iTbsbUL8C3N9m4tfEbCmyR8WMKJgAsKwKC1WPubtTDr0VrCrfv6R1t6miFufFF8k73JE1++jMbjFwFcBCicZfePs6x1TAI8q2XNOCdzIowK59ibW8LZ9mZhQVgpbHH1hdu3drU05xYUdJcvC7Mmt703TPb14WSHJKEmqSZsbAqbpBrNK1ZDN2njy6ZGb560UG+PI6HP3ue6rCusuLqFjhQH9DaHs6583To3hPDUpq7r58/mKqMtVq8mhqOj12vhqa1d82cLxLW7GzLAywtbe0ZbofpmOLGtQ4M2fl13V5hdB5WaWIlYVWx9HnuLwPR8RgvH2dfb+0c/04PQ5IyGadv+gkhOjvNY9DTltGijnV32gnBDrr3b1Zw3nk6j2/ZPZDu17IUz5cvGLSkxx44nJetAQuJ8wDM7JyFJLqC2bbOeZcIi+0YkRFhza7Cky441rRIXzyoada8CGV7dDFzhPkTEG45r6hm1rBF4wR82FFrs2ugfCRlgP/P2QoxLxxgLLX8kAYo8mU01zM/AYYcjXFYmUsTUhJjCxnVyXFu+bN8kX2n3WzR0cB+1w7eu7jWVcH9BgQjwTZNO6sUgfGhrV2ysUW9uhJyVju4w7xEzUzMzGdvFzKGZmVn2Hjsy+ah8EMgIm4tm/yVbMtNa+teEWebHTHti820d9ratO7q0ltEe3bdtnQtGsflVs3M6FE5r6lJyuQ7xXEXOIikvmyUWg66EsFqIf0aZ1H1hBUkpEUxrDVt6NsSu3fEFBR/JM2kyz2OajL4juGQ3x6ZbGV7jWDheu2C8wLqEUQX2qkW8rXPH6Gj8grlWFKDR0Va71jraM+qajB7qtWsW++gx/jB/eNTf0jMT0Mno8Ztyw603d2MR/WwNkpXT+nE7u2HruJPd0LGj65gFT283dHZFOONNPeu7x5dirusYbkWcEstnsWKkiRG1MSR6hJvlVO4xJ9EhOatKhBy7JxlJnHkGx8g9yWM4i8ThVY7bFBF8A9449U20/ihn00bTJG9wppFBnVYo3qROM8o2Gw3TXHmaFVEcbnatZHVY3qs/W7/Z8m79prP11ADY8gEuy6sKUgpSCnFhuIH4QFOmPnAa6C+kqVPQhScYMrjwnGUhGx10rigxlMRfnOVRPQmGsqzVWRsyuzP7Mw2rs1bmXp97t+GuRQZbSiEjnpZamGwxZxcfMTHTZHRqIm5RDUy82Zl2qIBpBVUFvCAlVSPNUmXhlkl+04S2vMPqgGk7hW2bLDv3vufYu+mMNLJB2kg797KdaQXVWZmZqRnpuBfE217AUlZU163jtTVFRcVF9jt4/lM9V032lNft3nRN79fPvsxKXv1c3YZd9fUDHeueMBzPK3pu+s0fPnHNmLutzKY+90FtUuolLzz22JO7U5PEs/ct0d+oHbivy6R7nVmfStmTcpdBiTNmG+t5fUobb0t5k5uSJ3nQmaIuyqT4jPT0+DhjWnpRRgZNslJnUqZTW1pzJJNFM1lmjhWLdmYuWVpz2Dpm5X7rO1b+eyuzxi8qijOLqWTQjpnZO2Zmzs5qqJdr3zvsEKvfjNUPO95D23Sm3iIjVW+BFxrOCC+wnQW1RqN9SVFRLaKWnpm5onrlSgEqm9c84738sU+ybNu2hg3DZSz7vu29n37sLj42bT3tWbsl9Dqb+svPxToP4H73y+o6KmZrj1EpjNmZEt9gMBoTMoyZCTVKjbnGWmNv5i3mFmuzPUFTKks74npKD5XeV/p148OmhxKeMD6REC49VXq6NIlKK0vbMXGy9LVSY6kzJ6+mAeNDctJgKlBNOfmZcFkk3lQgPLdYNVlSUopz8/KKiuMZGZMtRakpzh21PSnMl8JSJnmrMzkntyg/DzhfHuvJY3nAHS1EdBl8HCEqFsmUHNcgeudK2F0M0mJnI1o92tLimmLnmotqKotfKn6tWEkuthUfKlaoWCuuKo4Wq8XZJb+K+Vq4OPZCtp2Bl9/budeBRHtv707RwefS6+LdcKbhDEtJXU1oy6vYsGPvToTBkVaQsXJFdWbWSnnNzEAIapCDS4xGCRbNgAeYctPU7ruqWh+4LPRASf70m/nFW9f2V0y/ubhhZWN/+fSbatFtj3Zu396567LmL5/t5ru+WlG/4aa7pjlvvWfHstZr7z77AWKWNL1V3YbcTGM1R1NLDCxtMnraaU1IrjFnJibXmMTFKC6GTOC4cI4tZ00NgqomLkoyWjilGdU0rioKg9vTeizMMsmOOFMXJSdWJpWQllGV0ZOhvJPBMoR/lxTViN6Zmre4JiMrK0ddrTit2TUHFaZMsmJnHJcjVD8xSsXTiTNvZY1GVagW2enfGYs52LHpbDau+Gc9u7nF0/xrh2Pv8CbLu69Tw5mdlQ3StSx1dYr0a+pqAKYki9joDibjsrMtbOloC69BxY+oFjoefYdY9J1xBc/veHXjRDlGhuhvnEmJKQ1plrRsXFKtDQacIRMYiD6CcUxWd1pBWloBMyUp9iXFxWLL1CUxx/T7zD59Y1Nh06cOtm/dnL2+tvfT2WrR2ST+hw/4sZ29Fy1J+UVioFvUwDvxLPg+amAy7rdHnIVGw7H0Y1blYgPbY/iJgaemFCYmJVGupRAuSSZz5jlVL9OWX5Xfk+/PP5RvyLckayzmLFH48hYWvtm6J6pe6urKudq3IqVAQ/HLSDeKymfP5nLj14i6dyf7V5a07cBjvV/a/JnvP/vAkX1Nn95QO2Y4nlnw6pHrJ70pGWd/qj433VPR29jenxiPbPoS1nMt1hNHw84Gs0E1GgpNmrnKfNL8mlmtNB82c7OZFFWsJ47MpgbjFjyKb1Nw8vAcbVHVIr5IjZu/iPj5i0D9eg8ABnPL2LkXvWKw1GM1WEhGgWxfUs6cXcv7zt5rOP7+9IPvn71NVCcrHP5rw8uowpPO6pUqK1M1i5bSrR6yGszqSSvPyEzh6amZKUlpyWRJSmNk4elx5uRFbNeiKAwTZSbeyFKSY4VYVh2c13jYFomPkr2iwbzF3G5WzCWWypRdKTxlkqnOxKS0Ip6+i8YypzJ5JkL3ZFxCTWZ21hXHuJfk0hx76zeJ0/KDnfXv7sx+naxYm1gVWgMuq6uT8UJ5EMUhbUVtjSgLWSZRBDIyVmTYURLs1ntX3x26IlDUtO6i2n/+5+k371WL2r9wbcfS71hWb2179YOnlI0i126Hsd9AbMTZPnKM4rAPG1DnnHHtcfxQXDhuKu5U3O/jDLa4nriDcWNAGBSjCQe/kkzMSafwxKjQTtwiGA1GkxrPTUVMFXs5rmBpjZpt1o8ah34LIAOEJcjQyOhgAcOONJjL0G5n2dNvsmz1SaZOf/CXT6hFOEDYPAs7xBaccpYK+wztBn7IEDZMGU4Zfm8w2Aw9hoOGMSAMMAY3JVwpYjRjCWWr51ii614R02s4/udWeKMRZ3Ixzqp0ymNfO0aW6PvO1kWr7477SuJdlkcMD8efiDuROJljNqezDfxiY2v8lsWPJD5pfDLnu/HfS/hJ/CsJ75v+lJiYl5yX4czNr8lwJqXUJGeczHgpQ5GFLnlxg+yTstDzW5wJyUmp7Uk9STzJmspEFmTn1rAVqcLsiXytRvZLSmO9ozzWW/Nk70xOSq4ZE/flFpi9KzUVmTehLkq1igxcushEBawyo2BLEkvKqVy8a7Fv8X2L1cXJBWYnirY5O9/bGPPGpjNy+2w68y6KwBkUOWe61VmS3mB1Lk7GJdeCS15KgyxqDWdlEUyFEaBIFcaASPagE31khhTnnSyEkoEwgeNMzGeJLjwRF79ODhsLGhwk6F93oCjvlOqTnPBSklCaJNQnOeEskkJRnBwOHKP1uAtD8HbupZ0OhiPHrhUX1VpoRTUpBfL+JE0chiZjFv8zs65868j0767zsvSXz7BU41mncrVr/Y5i5YpLLquvZ2xb5Vfuf+K2V5kZ1fm70898/qYNbODKg01NAfkxmPiI79d7nvlx/8ldyfV/NGeb5adDD/yqfu5Tf5reavwyqgdDbWMzH58RmdZNb6amuQ/UPvQBU4IRKMN36Q71V3SLKZ8OqAFK4qtx53sJ3Qncl/hjZMX4dtEw1wielfQ4s7H/5JN8UtGUIeV/qw1qyPBZXXoClSANxIsjISppO+65Nlt82AgCu0u9ksTduzRYXhXJFy9HiuTCnaEOK9TFLDqsUjrr12EDWdnndNgI+A4dNtF32Dd02ExF3K/DcTTK79LhePU5RdPhRdRr+qUOJ9Buc7MOJxqPmh/T4SS6LPnTs347mHxch+E2y2od5qRa1umwQsss63VYpXjLkA4bKMFyhQ4bAV+rwybqtRzWYTOlWf6gw3HUkmLQ4XjuSvmEDi+i5WmPz35btiLtFzqcqOxIT9bhJKrI8sISpgqvJ2V9SYdVysl6UMIG4OOzTuqwSplZ35ewEXhj1ms6rFJq1hsSNom4ZP1JhxGLrKiEzcAnWNN0WCWr1SbhOBFfa50OI77ZtToMOdkNOoz4Zl+sw5CZfZ8OI77ZEzqM+Gb/ow4jvtm/0mHEN+dhHUZ8c17UYcQ391M6jPhq2TqM+Gqf1WHEV/tfOoz4Ft8p4Xjhq+J/12H4qji2xkXAp5Zk67BKi0scEk4QaynZqMOwv2SrhJNE5pd4dFilvJKQhC1Szm06LOR8TcJpwuclz+owfF7yXQmnC3tKfqbDsKfkTQlnAJ9eynRYJa00Q8KZgr60VodBX9ok4WxJv1OHBf1eCeeKHCi9TYeRA6X3SDhf2FM6rsOwp/QpCdsk/fd1WNC/LOGlIgdK39Jh5EDpHyVcJvxTlqjD8E9ZzM5yUQnKSnVYnYHN0v+zMOwvk/ljlusq26rDAr9LwAkx+v06LPDXS1jGpex+HRZ6H6VO2k9+8tBucpEbvUaPonVSv4Q3kY+G0II6lYaK6aNhwOLqAt4rKTRgBsBfAahZ4l3/Q0mVs5Zp1IGZAQrN0gSA24g+pm85rca7isp1qFpiG8ExgH4bePbAhqDk2gZ5AbRh2odrH6iGMe8C5Xqpo+8cO9fMo9FmqdbQJVJKYNbqFdBahbeGKr8JWDdmfZj3wbNBKj2vlI+SMUdbPs+uznn4b0nPCr/1QcYg+mG6HDih7b/vcw1YD7zlhU1BaZvwkYaxoAnqUrcjHhq1S36NiqS+Tbhuge7d0vcu0As+D6QKb49ITiGt4jw2xeLsg15hkx+0+z+SyiPzS9CNSKv2zOr16tlbLqPso17d6s1ypl960QVrls3aPixnvDJTO3ANSatjEYll1SrkUpO0JCi9POO3Ydiigcql52Iso7zS930yw0TODUld8+Pu1mW5pG2Cc1BKFHb3Q/+glBjzviatdkl9bj0asRlhdUCPh0uuMca3fzb+Xj3b/XoEPdI3AZmNsdXNRMil2x+S2jSpYb5VM5EXvhHjESm7f142CFqflBXTPYOPeTuoe8StZ2rgHLogZHqkV7zoY7LdOiYkPS0yai6nfXLnDkuPDkh+YamI56DONaPBLfn36Vq9+kpj+1FImPPCblAKaTHsnF+9und9+kq8kj4kR3NRDcgsHZDWnT8nZmprYHYtYm5QypuTIerF5bq1Lt3/bln1NH2XzvisT+reI7ExfrHDvHoM++W+8+s54sNV7Oh9urdjEuaqvUvGKpYdmvShW1+/V0ZtQNL45d6LZeOQ5IytZH52e2czS+z8K/TIDEprRG7u0/dWrO4MzNoxKEdz2Rv80IkU+ND63LqOXikhJD3dtyA3PbQX+BnPitx2z65wt8xtTebAFdK3AZl3wdl6Eou6sD2234N61YjtpoCeZXPVMzY7KCPioislf8xqIdctZ+cyLaa9T3rLL3fJ/tlVzOgekjVTzLukJ4Z1HWIPxbwYlPwzFs9I98scGpR1c8a2Cnn2BTG3BmdqJeSKd4Wkml9hK2R1GgRFv9xLA4AGAQ3JCHnkKEC7ZA7EIl4xS/l/V8OIzJgYrWeels2o9J0491vRmpB5At4CrDgBWnH9pMS3ANOBq8jNi3EStOC9SWI7KRFPU6J1ymwKnCfXtFl8bJ/EPOrXfT6Xo3/dKTYXmZmKPBPnXjm7H/ShWZ3u2doWy+e582h+tYxVjrk6Gtu/Xr1mBvQ9vUdK8czWRLFbu3VtYnfv02tp7+xpFNMZ/BjPzNTOkdnq5NF3nGc2p4dl/Qjq+3m3no/n89fMLhQe88yTMreLz9XXp5+AIgN7ZWWMWd2rR2ZIl3y+CBXLVS30VKwin5sV52qeqW2iirnkvagLWgd0bwf0GvJRuoX3twMzV2f3nxMLj36XMf+eK1a9XdIiv/SsV7/T+Wtirum5ODSvts3oFZWkT3raO+8UGZ53r7xslnp4Xt7Ond0f7ylh3aCUP5NXvgXyRmT8L5fRnH8fOlMf5yh9oI3doYakx4X8/tn1xOyan92DekWN+T+2q/x6fsxV3oU59HErmsuPjXLt50Zu5t5LnDke/Q4ttprY/Z5bRnXoQzEY/pC/5yQH5N1qSN71x86hffLeaITm313919GfkTes3/959Wee893FnRvHmLfm7ljdUua5+3gmYq4P+Xr332TtnJfP1bDwvF9okUe/iw3i7JmRIJ5PGin2JFCCe/gaqsPzl4brcozK8XxVI5+yxKcj26lNp6zC7HLM1OhwHZ7G6iTXSqrFs4BoQvrfdtb990/GmbnKD3lv9jzs3O/37Ha5PdqjWme/R9vkG/IFgdKafMN+37Ar6PUNaf4Bd4XW7Aq6/guiSiFM6/ANhAQmoG0cAt/y1aurynGprtAaBwa0bd49/cGAts0T8Azv8/Q1DntdA+t9A30zMtdIjCZQay7xDAeE6BUVVVVaySave9gX8O0Ols6RzKeQ2HIpq1PCj2idw64+z6Br+HLNt/tjLdeGPXu8gaBn2NOneYe0IEi3d2jtrqBWpHVu0rbs3l2huYb6NM9AwDPSD7KKWUlYs2/PsMvfv38+yqM1D7tGvEN7BK8X7i3Xtvl6IXqz193vG3AFlgnpw16316V1uEJDfVgIXLWqusk3FPQMCtuG92sBF7wIR3l3a32egHfP0DIttnY3qFxeTA76hj1af2jQNQTzNXe/a9jlxjIw8LoDWIdrSMPcfrF+L9zuxwI9bk8g4IM6sSAX5Ifc/ZpXFyUWHxryaCPeYL90w6DP1ye4BQyzgzDEDacGZnDBEc9Q0OsBtRtAaHh/hSY97dvnGXYh3sFhjys4iCnB4A4h5gGhTMTRMyxN2B0aGAAobYX6QR+UeIf6QoGgXGoguH/AM98TIlsDQotneNA7JCmGfZdDrAv2u0NQFAtgn9e1xyfmR/rhc63fM+CHR3zaHu8+jySQae/SBuAObdAD3w153SB3+f0euHHI7YGSmLu9wlma5wosZtAzsF/D2gLInQEhY9A7IN0b1DdSQNfnBkevRwsFkFLSm569IWFsyC38r+32YcmQiEUFgyJPsPRhD+IeRGogTAG4TKYnhoOuPa4rvUMQ7Qm6l8WcBvY+b8A/4NovVAjuIc9IwO/ywzSQ9MHEoDcgBAty/7Bv0CelVfQHg/41lZUjIyMVg3rCVrh9g5X9wcGBysGg+NuSysHALpdYeIVA/pUMI54BYD2SZfOWzo2tG5saOzdu2axtadU+ubGpZXNHi9Z48baWlk0tmzsT4xPjO/vh1hmvCReLmMBQrCAoPXqeLSYXIxJZrLl3v7bfFxKcbpFt8LPcR7G0RHLIHEV8sf2GQO7aM+zxiEys0LrB1u9CGvh6xTYCZ3CBMSI7R0Q6eRA4j/D0sMcdRJx3w49zdokQ+vZ4JIkM8SwfQoPs7Q0FIRpm+rCj5i2oODBjFBJ51hWzzCLbtH2ugZCrFxnmCiBD5nNXaNuHZM7un1kF1qRXLqS3Swv4PW4vis65K9fgxSGZbYLX1dfnFTmBrByWVXmZQA9L38rd/SGjBryDXrEgKJF0I77hywOxJJX5KJG+ERTUUO+AN9Av9EBWzN2DSFTYj1D592ux5NU9tFCR9MfG3XOLE9Vrb8gTkGpQ99ye4SF9BcO63ZI40O8LDfRhD+3zekZi5eqc5Qs6RNKDCtA3V+Jm1wizZGF1B+diLBbm0q3efX6x0uRZBn3f64KgxxVcIwi2dzTiEChZVVNXqtUtX1VeVVNVFRe3vQ3IquXLa2pwrVtRp9WtrF1duzox/iN23cduRjGq1M2T+xCPqx79Jknc6sz/mGXhTJBCLBG3Bm8toJnD7qaFH3NrOqZV/9Bj/oyOU25QnlG+o5zEdXz+/AL8ha8NLnxtcOFrgwtfG1z42uDC1wYXvja48LXBha8NLnxtcOFrgwtfG1z42uDC1wYXvjb4f/hrg9nPD7z0UZ8sxGY+iT6WrT6JCS2gPXf2Ylk1AguoZnCt9BbGl9N7oH8LuIWfOiycm+GZub/ynVfi3OwlEppPE8NskKN98vOOhfMLZ9r10zckn/18clfOpz7f/HxP+T7Shz7Vpq5T16pN6kp1lepUL1Lb1NXzqc8733neT3TmsK3nrCeGaRMjthw08+fmsG36venlH7J4Hp6l0C8VO7Jk3vws7q/Nm7/SN3+1vI/LK/3/y1O0mH5K53l9mzqVr1AyY2SLTilfnrCkVzsnlbsnktOqnY0W5U5qR+MUVjbRFBonn3IbHUTjIG+LlC+vPiaAifikagvobyIN7RCaQmO4Mjl2ogn6mybSMoX4ayLJKZLvs5GqmhgwYbFWtzemK1cQUzzKENnJphxAvxi9G30++l6lD5VC2OmcSLZUH4K+BpA3KBkoQzalUcmkavTNSg7lSrJQJCmmJxQpKatujFeaFKskSVYSUY9silkxRapt2glF/NmwU7lhIm6RsO+GiCWj+hnlOsVE6aA6BKosW/IzSjxVoomVdE7EJVYfbkxQOrHMTrjFpoj/rH+fvDqVoQgEQV+LkkeZmLtcyacM9K3K4kiGbeqEcrsk+zshBfrWRcwrRDeRmFQ91RiniL8HCCu3wuO3Sm2HJ4pWVVNjkVJCVYr4EwlNOQjooPjP4soooFGEaRShGUVoRmHFKBkR+RsxcyNoKpUrya+M0GG0+wCrEJkRgQePSWBpSfUxJVuxwhOWE/AdAzZnIi5JWGaNpKZJMutEQlJ1wzNKgLagcRgfnMiyVvtOKGVyKcsmrLmCwR+JS4DrsmKxAGOmiMEzSp6yWHoiX3og3GjDmFGyYiPGf8BPCe/wl/mPRXzFT/rI/h/1/kW9/2Gsj07xUxPQ4pzk/yz60415/A0I28VfpfsAcX6CP4+jxsZ/zieFFfxn/Bg1oH8F4z70x9CvQH88UvA92ySfnEAH2++JJGaKxfLnI45KHbAV6kBWrg6kZlY3FvLn+LOUBxE/Rb8U/bN8ipagP4nein6KB+l76J/gtbQW/VG9/w5/WuQ0f4o/iTPTxiciScKEcMQkuiMRo+i+FaHYqL3S9jT/Fn+cckD6zUhRDrCPTBQttSWfgDzGH+TBSL4ttTGe38+62LsgGqNXRE+p/IFInRByOPK0ZjvGD/PDTmuds9BZ7nxIqSqsKq96SNEKtXKtTntIa7TwW8kA52HD8ptwxfnMkT1oTrTD/MaIWhduPIs1iXVxOoTrmIR6cPVLiHC1zM6+I6EGfh1tQeOQcQDtINohtKtIxfVKtM+ifQ7t8xITRAuhjaB8+MHhB4cfHH7J4QeHHxx+cPglh19qD6EJjh5w9ICjBxw9kqMHHD3g6AFHj+QQ9vaAo0dytIOjHRzt4GiXHO3gaAdHOzjaJUc7ONrB0S45nOBwgsMJDqfkcILDCQ4nOJySwwkOJzickqMKHFXgqAJHleSoAkcVOKrAUSU5qsBRBY4qyaGBQwOHBg5Ncmjg0MChgUOTHBo4NHBoksMCDgs4LOCwSA4LOCzgsIDDIjksMj4hNMFxGhynwXEaHKclx2lwnAbHaXCclhynwXEaHKf5yLhyqvEFsJwCyymwnJIsp8ByCiynwHJKspwCyymwnNKXHpTO4EibA2gH0Q6hCd4p8E6Bdwq8U5J3SqZXCE3whsERBkcYHGHJEQZHGBxhcIQlRxgcYXCEJccYOMbAMQaOMckxBo4xcIyBY0xyjMnEDaEJjr89Kf/m0PCrWJcZhys/xEplf5Delv0BekX2n6dx2X+OHpL9Z+lq2V9JdbIfoSLZQ57sg2Qzs4itLrkxEyVgC9ouNB/afWhH0E6imST0EtpraFFe61yiJpu2mO4zHTGdNBmOmE6beLJxi/E+4xHjSaPhiPG0kWuNuTxR1lGUFvqivB7E9fdoOERwbZBQA6+B3hrU2Vq8a3iNM+WM9vsy9lIZO1nGjpSxL5axxjh+MVNlpcOdPofhrMuZULTO9gpaXVHxOlSmW598O8sWKVppm2RPx7pSpwP922jjaA+hXY1Wh1aNVo5WiGaTuDLQdzmX6CKfRitGK0DThArKzMTdTWqK2XmMJ7KHJl5IpDihp7gEfCcixVXoJiPFW9A9FSnutTXGsSepWNwGsScQucfRH4nYXsf0N2PdNyK2E+geidhq0O2MFFeguzRS/KKtMZFtJ5sqWDv1vgPrFv22iO0SkG2N2ErROSLFRYK6DIoKMVvKuuh19IU619KYJnvEthbdkohttaA2U7EIPDNSuTTPgCZ6ZQIG/f4Y61KZc5HtjO1229tg/x0ci/T4mTaponupcJJd4oy3PV3+VRA32iKN8YIe58O43odF/4TtocIbbfdAFit80na3rcJ2a/mkGehbYPeNUkXEdrU2yR93ptkO2apswfLXbQHbJ2wu2zbbzkLgI7bLbE8LM6mbdfHHn7S1Q+BGrKIwYru4cFKa2Grbb3Paim2rtaeFf2lVTG5d+dPCA1Qd074M/i0rnBQ5vr1ukqU4y0zvmA6bLjWtN6012U1LTItN+aZ0c6rZYk4yJ5jjzWaz0ayauZnM6eLnHRzizyvTjeKv18moiqsqYQsXVx77S1POzJw+QeE0pY23daxnbeEpN7X1auH3OuyTLH7rjrDBvp6FU9uorXN9eJWjbdIU3Rauc7SFTe2Xdo0zdms3sGF+wySjzq5JFhWo63LFD1GNM7rultxjxFj2dbd0d5M1c1+DtSF1Xcrq1ubzXHr0q2PuZZ0P5ofvauvoCj+W3x2uFkA0v7stfJX4mapjPJkntjQf40mi6+46pvp5css2gVf9zd0ge12SIZuTQEbFogOZeT1pggz1ZL0gQ4xidEVgB12B6EAXn0hFkq4oPlHSqUzQjb+itTSPa5qkKSR6RdK8UkjzaJAx4G0eLyqSVHaNdQkq1mXXpGGlUpDNBpJymyTBk5tNCrIxqSxcOUdSqJPUzpLUSl0Km6OxxWjSS2Zo0ktA4/gfvjzrHWxieejA8+KXv3rsLR60nvBN+/qt4UO9mjZ+IKT/JFhRT6+7X/QuTzhk9zSHD9ibtfHlz59n+nkxvdzePE7Pt3R2jT/v9DRHljuXt9hdzd0TDfVdjQt03Tirq6v+PMLqhbAuoauh8TzTjWK6QehqFLoaha4GZ4PU1eIVed/eNW6m9eJ3QWQ/wRfFI4d7cgu612da/OtEQh9bW2A9kHtcJfYILXJ0hxPs68OJaGKqvLG8UUxhn4mpJPHzbvqU9cDagtzj7BF9ygJ0in09zbiWBFFbuHZrW7igY0eXSJWw03X+mAXES05bqcXbjH8YB2XDez4lBc77Cp7vFQqFAuIScuApuS1c1tEWXrkVlphMUNXT3A1cxQxOUSRuPC6uZTI6hUkHjGBBoU5ADiZ+I8AZj6cuEx8zjpm4eFQITuTkV/uewQl+EA3PcXwkUimfl/nIxJJC8fwSnKisjfV4PhV9JKegWvwUQR1YRV8Y650p5QAOFx4uP1w3VjhWPlZnFD+08BCQtofEURqpfEihoCMw4wiAwW6K/XQB9N0fycuXiscE4HB0OwLyN17ow6526L8jA6fPOjagSw1I8cGZgMTwAYoRxyYdoRmmkM4iJ0OSRSr8P1jbNhMKZW5kc3RyZWFtCmVuZG9iagoKNiAwIG9iagoxMDgyNQplbmRvYmoKCjcgMCBvYmoKPDwvVHlwZS9Gb250RGVzY3JpcHRvci9Gb250TmFtZS9CQUFBQUErQXJpYWwtQm9sZE1UCi9GbGFncyA0Ci9Gb250QkJveFstNjI3IC0zNzYgMjAwMCAxMDExXS9JdGFsaWNBbmdsZSAwCi9Bc2NlbnQgOTA1Ci9EZXNjZW50IDIxMQovQ2FwSGVpZ2h0IDEwMTAKL1N0ZW1WIDgwCi9Gb250RmlsZTIgNSAwIFI+PgplbmRvYmoKCjggMCBvYmoKPDwvTGVuZ3RoIDI3Mi9GaWx0ZXIvRmxhdGVEZWNvZGU+PgpzdHJlYW0KeJxdkc9uhCAQxu88BcftYQNadbuJMdm62cRD/6S2D6AwWpKKBPHg2xcG2yY9QH7DzDf5ZmB1c220cuzVzqIFRwelpYVlXq0A2sOoNElSKpVwe4S3mDpDmNe22+JgavQwlyVhbz63OLvRw0XOPdwR9mIlWKVHevioWx+3qzFfMIF2lJOqohIG3+epM8/dBAxVx0b6tHLb0Uv+Ct43AzTFOIlWxCxhMZ0A2+kRSMl5RcvbrSKg5b9cskv6QXx21pcmvpTzLKs8p8inPPA9cnENnMX3c+AcOeWBC+Qc+RT7FIEfohb5HBm1l8h14MfIOZrc3QS7YZ8/a6BitdavAJeOs4eplYbffzGzCSo83zuVhO0KZW5kc3RyZWFtCmVuZG9iagoKOSAwIG9iago8PC9UeXBlL0ZvbnQvU3VidHlwZS9UcnVlVHlwZS9CYXNlRm9udC9CQUFBQUErQXJpYWwtQm9sZE1UCi9GaXJzdENoYXIgMAovTGFzdENoYXIgMTEKL1dpZHRoc1s3NTAgNzIyIDYxMCA4ODkgNTU2IDI3NyA2NjYgNjEwIDMzMyAyNzcgMjc3IDU1NiBdCi9Gb250RGVzY3JpcHRvciA3IDAgUgovVG9Vbmljb2RlIDggMCBSCj4+CmVuZG9iagoKMTAgMCBvYmoKPDwKL0YxIDkgMCBSCj4+CmVuZG9iagoKMTEgMCBvYmoKPDwvRm9udCAxMCAwIFIKL1Byb2NTZXRbL1BERi9UZXh0XT4+CmVuZG9iagoKMSAwIG9iago8PC9UeXBlL1BhZ2UvUGFyZW50IDQgMCBSL1Jlc291cmNlcyAxMSAwIFIvTWVkaWFCb3hbMCAwIDU5NSA4NDJdL0dyb3VwPDwvUy9UcmFuc3BhcmVuY3kvQ1MvRGV2aWNlUkdCL0kgdHJ1ZT4+L0NvbnRlbnRzIDIgMCBSPj4KZW5kb2JqCgoxMiAwIG9iago8PC9Db3VudCAxL0ZpcnN0IDEzIDAgUi9MYXN0IDEzIDAgUgo+PgplbmRvYmoKCjEzIDAgb2JqCjw8L1RpdGxlPEZFRkYwMDQ0MDA3NTAwNkQwMDZEMDA3OTAwMjAwMDUwMDA0NDAwNDYwMDIwMDA2NjAwNjkwMDZDMDA2NT4KL0Rlc3RbMSAwIFIvWFlaIDU2LjcgNzczLjMgMF0vUGFyZW50IDEyIDAgUj4+CmVuZG9iagoKNCAwIG9iago8PC9UeXBlL1BhZ2VzCi9SZXNvdXJjZXMgMTEgMCBSCi9NZWRpYUJveFsgMCAwIDU5NSA4NDIgXQovS2lkc1sgMSAwIFIgXQovQ291bnQgMT4+CmVuZG9iagoKMTQgMCBvYmoKPDwvVHlwZS9DYXRhbG9nL1BhZ2VzIDQgMCBSCi9PdXRsaW5lcyAxMiAwIFIKPj4KZW5kb2JqCgoxNSAwIG9iago8PC9BdXRob3I8RkVGRjAwNDUwMDc2MDA2MTAwNkUwMDY3MDA2NTAwNkMwMDZGMDA3MzAwMjAwMDU2MDA2QzAwNjEwMDYzMDA2ODAwNkYwMDY3MDA2OTAwNjEwMDZFMDA2RTAwNjkwMDczPgovQ3JlYXRvcjxGRUZGMDA1NzAwNzIwMDY5MDA3NDAwNjUwMDcyPgovUHJvZHVjZXI8RkVGRjAwNEYwMDcwMDA2NTAwNkUwMDRGMDA2NjAwNjYwMDY5MDA2MzAwNjUwMDJFMDA2RjAwNzIwMDY3MDAyMDAwMzIwMDJFMDAzMT4KL0NyZWF0aW9uRGF0ZShEOjIwMDcwMjIzMTc1NjM3KzAyJzAwJyk+PgplbmRvYmoKCnhyZWYKMCAxNgowMDAwMDAwMDAwIDY1NTM1IGYgCjAwMDAwMTE5OTcgMDAwMDAgbiAKMDAwMDAwMDAxOSAwMDAwMCBuIAowMDAwMDAwMjI0IDAwMDAwIG4gCjAwMDAwMTIzMzAgMDAwMDAgbiAKMDAwMDAwMDI0NCAwMDAwMCBuIAowMDAwMDExMTU0IDAwMDAwIG4gCjAwMDAwMTExNzYgMDAwMDAgbiAKMDAwMDAxMTM2OCAwMDAwMCBuIAowMDAwMDExNzA5IDAwMDAwIG4gCjAwMDAwMTE5MTAgMDAwMDAgbiAKMDAwMDAxMTk0MyAwMDAwMCBuIAowMDAwMDEyMTQwIDAwMDAwIG4gCjAwMDAwMTIxOTYgMDAwMDAgbiAKMDAwMDAxMjQyOSAwMDAwMCBuIAowMDAwMDEyNDk0IDAwMDAwIG4gCnRyYWlsZXIKPDwvU2l6ZSAxNi9Sb290IDE0IDAgUgovSW5mbyAxNSAwIFIKL0lEIFsgPEY3RDc3QjNEMjJCOUY5MjgyOUQ0OUZGNUQ3OEI4RjI4Pgo8RjdENzdCM0QyMkI5RjkyODI5RDQ5RkY1RDc4QjhGMjg+IF0KPj4Kc3RhcnR4cmVmCjEyNzg3CiUlRU9GCg=="}}}]},
5
+ {"role": "assistant", "content": [{"text": "foo bar"}]}, {"role": "user", "content": [{"text": "Here is another PDF
6
+ document: "}, {"document": {"name": "Document 2", "format": "pdf", "source": {"bytes": "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CmVuZG9iagoKOSAwIG9iago8PC9UeXBlL0ZvbnQvU3VidHlwZS9UcnVlVHlwZS9CYXNlRm9udC9CQUFBQUErQXJpYWwtQm9sZE1UCi9GaXJzdENoYXIgMAovTGFzdENoYXIgMTEKL1dpZHRoc1s3NTAgNzIyIDYxMCA4ODkgNTU2IDI3NyA2NjYgNjEwIDMzMyAyNzcgMjc3IDU1NiBdCi9Gb250RGVzY3JpcHRvciA3IDAgUgovVG9Vbmljb2RlIDggMCBSCj4+CmVuZG9iagoKMTAgMCBvYmoKPDwKL0YxIDkgMCBSCj4+CmVuZG9iagoKMTEgMCBvYmoKPDwvRm9udCAxMCAwIFIKL1Byb2NTZXRbL1BERi9UZXh0XT4+CmVuZG9iagoKMSAwIG9iago8PC9UeXBlL1BhZ2UvUGFyZW50IDQgMCBSL1Jlc291cmNlcyAxMSAwIFIvTWVkaWFCb3hbMCAwIDU5NSA4NDJdL0dyb3VwPDwvUy9UcmFuc3BhcmVuY3kvQ1MvRGV2aWNlUkdCL0kgdHJ1ZT4+L0NvbnRlbnRzIDIgMCBSPj4KZW5kb2JqCgoxMiAwIG9iago8PC9Db3VudCAxL0ZpcnN0IDEzIDAgUi9MYXN0IDEzIDAgUgo+PgplbmRvYmoKCjEzIDAgb2JqCjw8L1RpdGxlPEZFRkYwMDQ0MDA3NTAwNkQwMDZEMDA3OTAwMjAwMDUwMDA0NDAwNDYwMDIwMDA2NjAwNjkwMDZDMDA2NT4KL0Rlc3RbMSAwIFIvWFlaIDU2LjcgNzczLjMgMF0vUGFyZW50IDEyIDAgUj4+CmVuZG9iagoKNCAwIG9iago8PC9UeXBlL1BhZ2VzCi9SZXNvdXJjZXMgMTEgMCBSCi9NZWRpYUJveFsgMCAwIDU5NSA4NDIgXQovS2lkc1sgMSAwIFIgXQovQ291bnQgMT4+CmVuZG9iagoKMTQgMCBvYmoKPDwvVHlwZS9DYXRhbG9nL1BhZ2VzIDQgMCBSCi9PdXRsaW5lcyAxMiAwIFIKPj4KZW5kb2JqCgoxNSAwIG9iago8PC9BdXRob3I8RkVGRjAwNDUwMDc2MDA2MTAwNkUwMDY3MDA2NTAwNkMwMDZGMDA3MzAwMjAwMDU2MDA2QzAwNjEwMDYzMDA2ODAwNkYwMDY3MDA2OTAwNjEwMDZFMDA2RTAwNjkwMDczPgovQ3JlYXRvcjxGRUZGMDA1NzAwNzIwMDY5MDA3NDAwNjUwMDcyPgovUHJvZHVjZXI8RkVGRjAwNEYwMDcwMDA2NTAwNkUwMDRGMDA2NjAwNjYwMDY5MDA2MzAwNjUwMDJFMDA2RjAwNzIwMDY3MDAyMDAwMzIwMDJFMDAzMT4KL0NyZWF0aW9uRGF0ZShEOjIwMDcwMjIzMTc1NjM3KzAyJzAwJyk+PgplbmRvYmoKCnhyZWYKMCAxNgowMDAwMDAwMDAwIDY1NTM1IGYgCjAwMDAwMTE5OTcgMDAwMDAgbiAKMDAwMDAwMDAxOSAwMDAwMCBuIAowMDAwMDAwMjI0IDAwMDAwIG4gCjAwMDAwMTIzMzAgMDAwMDAgbiAKMDAwMDAwMDI0NCAwMDAwMCBuIAowMDAwMDExMTU0IDAwMDAwIG4gCjAwMDAwMTExNzYgMDAwMDAgbiAKMDAwMDAxMTM2OCAwMDAwMCBuIAowMDAwMDExNzA5IDAwMDAwIG4gCjAwMDAwMTE5MTAgMDAwMDAgbiAKMDAwMDAxMTk0MyAwMDAwMCBuIAowMDAwMDEyMTQwIDAwMDAwIG4gCjAwMDAwMTIxOTYgMDAwMDAgbiAKMDAwMDAxMjQyOSAwMDAwMCBuIAowMDAwMDEyNDk0IDAwMDAwIG4gCnRyYWlsZXIKPDwvU2l6ZSAxNi9Sb290IDE0IDAgUgovSW5mbyAxNSAwIFIKL0lEIFsgPEY3RDc3QjNEMjJCOUY5MjgyOUQ0OUZGNUQ3OEI4RjI4Pgo8RjdENzdCM0QyMkI5RjkyODI5RDQ5RkY1RDc4QjhGMjg+IF0KPj4Kc3RhcnR4cmVmCjEyNzg3CiUlRU9GCg=="}}}]},
7
+ {"role": "assistant", "content": [{"text": "foo bar 2"}]}, {"role": "user", "content": [{"text": "What is in the documents?"}]}],
8
+ "system": [], "inferenceConfig": {}}'
9
+ headers:
10
+ amz-sdk-invocation-id:
11
+ - !!binary |
12
+ NjNjMWFiZTUtMjVhMS00M2Y0LWE3ZWQtZjE3MmYwODllNWFl
13
+ amz-sdk-request:
14
+ - !!binary |
15
+ YXR0ZW1wdD0x
16
+ content-length:
17
+ - '35917'
18
+ content-type:
19
+ - !!binary |
20
+ YXBwbGljYXRpb24vanNvbg==
21
+ method: POST
22
+ uri: https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-3-7-sonnet-20250219-v1%3A0/converse
23
+ response:
24
+ headers:
25
+ connection:
26
+ - keep-alive
27
+ content-length:
28
+ - '506'
29
+ content-type:
30
+ - application/json
31
+ parsed_body:
32
+ metrics:
33
+ latencyMs: 1820
34
+ output:
35
+ message:
36
+ content:
37
+ - text: Based on the documents you've shared, both Document 1.pdf and Document 2.pdf contain the text "Dummy PDF
38
+ file". These appear to be placeholder or sample PDF documents rather than files with substantial content.
39
+ role: assistant
40
+ stopReason: end_turn
41
+ usage:
42
+ cacheReadInputTokenCount: 0
43
+ cacheReadInputTokens: 0
44
+ cacheWriteInputTokenCount: 0
45
+ cacheWriteInputTokens: 0
46
+ inputTokens: 145
47
+ outputTokens: 48
48
+ totalTokens: 193
49
+ status:
50
+ code: 200
51
+ message: OK
52
+ version: 1
@@ -30,13 +30,12 @@ from pydantic_ai.messages import (
30
30
  UserPromptPart,
31
31
  VideoUrl,
32
32
  )
33
- from pydantic_ai.models.bedrock import BedrockModelSettings
34
33
  from pydantic_ai.usage import Usage
35
34
 
36
35
  from ..conftest import IsDatetime, try_import
37
36
 
38
37
  with try_import() as imports_successful:
39
- from pydantic_ai.models.bedrock import BedrockConverseModel
38
+ from pydantic_ai.models.bedrock import BedrockConverseModel, BedrockModelSettings
40
39
  from pydantic_ai.providers.bedrock import BedrockProvider
41
40
 
42
41
  pytestmark = [
@@ -560,3 +559,25 @@ async def test_bedrock_empty_system_prompt(allow_model_requests: None, bedrock_p
560
559
  assert result.output == snapshot(
561
560
  'The capital of France is Paris. Paris, officially known as "Ville de Paris," is not only the capital city but also the most populous city in France. It is located in the northern central part of the country along the Seine River. Paris is a major global city, renowned for its cultural, political, economic, and social influence. It is famous for its landmarks such as the Eiffel Tower, the Louvre Museum, Notre-Dame Cathedral, and the Champs-Élysées, among many other historic and modern attractions. The city has played a significant role in the history of art, fashion, gastronomy, and science.'
562
561
  )
562
+
563
+
564
+ @pytest.mark.vcr()
565
+ async def test_bedrock_multiple_documents_in_history(
566
+ allow_model_requests: None, bedrock_provider: BedrockProvider, document_content: BinaryContent
567
+ ):
568
+ m = BedrockConverseModel(model_name='us.anthropic.claude-3-7-sonnet-20250219-v1:0', provider=bedrock_provider)
569
+ agent = Agent(model=m)
570
+
571
+ result = await agent.run(
572
+ 'What is in the documents?',
573
+ message_history=[
574
+ ModelRequest(parts=[UserPromptPart(content=['Here is a PDF document: ', document_content])]),
575
+ ModelResponse(parts=[TextPart(content='foo bar')]),
576
+ ModelRequest(parts=[UserPromptPart(content=['Here is another PDF document: ', document_content])]),
577
+ ModelResponse(parts=[TextPart(content='foo bar 2')]),
578
+ ],
579
+ )
580
+
581
+ assert result.output == snapshot(
582
+ 'Based on the documents you\'ve shared, both Document 1.pdf and Document 2.pdf contain the text "Dummy PDF file". These appear to be placeholder or sample PDF documents rather than files with substantial content.'
583
+ )
@@ -692,3 +692,47 @@ def test_messages_to_otel_events_serialization_errors():
692
692
  'event.name': 'gen_ai.tool.message',
693
693
  },
694
694
  ]
695
+
696
+
697
+ def test_messages_to_otel_events_instructions():
698
+ messages = [
699
+ ModelRequest(instructions='instructions', parts=[UserPromptPart('user_prompt')]),
700
+ ModelResponse(parts=[TextPart('text1')]),
701
+ ]
702
+ assert [
703
+ InstrumentedModel.event_to_dict(e) for e in InstrumentedModel.messages_to_otel_events(messages)
704
+ ] == snapshot(
705
+ [
706
+ {'content': 'instructions', 'role': 'system', 'event.name': 'gen_ai.system.message'},
707
+ {'content': 'user_prompt', 'role': 'user', 'gen_ai.message.index': 0, 'event.name': 'gen_ai.user.message'},
708
+ {
709
+ 'role': 'assistant',
710
+ 'content': 'text1',
711
+ 'gen_ai.message.index': 1,
712
+ 'event.name': 'gen_ai.assistant.message',
713
+ },
714
+ ]
715
+ )
716
+
717
+
718
+ def test_messages_to_otel_events_instructions_multiple_messages():
719
+ messages = [
720
+ ModelRequest(instructions='instructions', parts=[UserPromptPart('user_prompt')]),
721
+ ModelResponse(parts=[TextPart('text1')]),
722
+ ModelRequest(instructions='instructions2', parts=[UserPromptPart('user_prompt2')]),
723
+ ]
724
+ assert [
725
+ InstrumentedModel.event_to_dict(e) for e in InstrumentedModel.messages_to_otel_events(messages)
726
+ ] == snapshot(
727
+ [
728
+ {'content': 'instructions2', 'role': 'system', 'event.name': 'gen_ai.system.message'},
729
+ {'content': 'user_prompt', 'role': 'user', 'gen_ai.message.index': 0, 'event.name': 'gen_ai.user.message'},
730
+ {
731
+ 'role': 'assistant',
732
+ 'content': 'text1',
733
+ 'gen_ai.message.index': 1,
734
+ 'event.name': 'gen_ai.assistant.message',
735
+ },
736
+ {'content': 'user_prompt2', 'role': 'user', 'gen_ai.message.index': 2, 'event.name': 'gen_ai.user.message'},
737
+ ]
738
+ )
@@ -4,6 +4,7 @@ import json
4
4
  from collections.abc import Sequence
5
5
  from dataclasses import dataclass, field
6
6
  from datetime import datetime, timezone
7
+ from enum import Enum
7
8
  from functools import cached_property
8
9
  from typing import Annotated, Any, Callable, Literal, Union, cast
9
10
 
@@ -175,6 +176,7 @@ async def test_request_simple_success(allow_model_requests: None):
175
176
  'model': 'gpt-4o',
176
177
  'n': 1,
177
178
  'extra_headers': {'User-Agent': IsStr(regex=r'pydantic-ai\/.*')},
179
+ 'extra_body': None,
178
180
  },
179
181
  {
180
182
  'messages': [
@@ -185,6 +187,7 @@ async def test_request_simple_success(allow_model_requests: None):
185
187
  'model': 'gpt-4o',
186
188
  'n': 1,
187
189
  'extra_headers': {'User-Agent': IsStr(regex=r'pydantic-ai\/.*')},
190
+ 'extra_body': None,
188
191
  },
189
192
  ]
190
193
 
@@ -558,6 +561,7 @@ async def test_system_prompt_role(
558
561
  'model': 'gpt-4o',
559
562
  'n': 1,
560
563
  'extra_headers': {'User-Agent': IsStr(regex=r'pydantic-ai\/.*')},
564
+ 'extra_body': None,
561
565
  }
562
566
  ]
563
567
 
@@ -634,6 +638,7 @@ async def test_image_url_input(allow_model_requests: None):
634
638
  ],
635
639
  'n': 1,
636
640
  'extra_headers': {'User-Agent': IsStr(regex=r'pydantic-ai\/.*')},
641
+ 'extra_body': None,
637
642
  }
638
643
  ]
639
644
  )
@@ -730,9 +735,15 @@ class MyDefaultDc:
730
735
  x: int = 1
731
736
 
732
737
 
738
+ class MyEnum(Enum):
739
+ a = 'a'
740
+ b = 'b'
741
+
742
+
733
743
  @dataclass
734
744
  class MyRecursiveDc:
735
745
  field: MyRecursiveDc | None
746
+ my_enum: MyEnum = Field(description='my enum')
736
747
 
737
748
 
738
749
  @dataclass
@@ -826,9 +837,13 @@ def tool_with_tuples(x: tuple[int], y: tuple[str] = ('abc',)) -> str:
826
837
  },
827
838
  'type': 'object',
828
839
  },
840
+ 'MyEnum': {'enum': ['a', 'b'], 'type': 'string'},
829
841
  'MyRecursiveDc': {
830
- 'properties': {'field': {'anyOf': [{'$ref': '#/$defs/MyRecursiveDc'}, {'type': 'null'}]}},
831
- 'required': ['field'],
842
+ 'properties': {
843
+ 'field': {'anyOf': [{'$ref': '#/$defs/MyRecursiveDc'}, {'type': 'null'}]},
844
+ 'my_enum': {'description': 'my enum', 'anyOf': [{'$ref': '#/$defs/MyEnum'}]},
845
+ },
846
+ 'required': ['field', 'my_enum'],
832
847
  'type': 'object',
833
848
  },
834
849
  },
@@ -857,11 +872,15 @@ def tool_with_tuples(x: tuple[int], y: tuple[str] = ('abc',)) -> str:
857
872
  'additionalProperties': False,
858
873
  'required': ['field'],
859
874
  },
875
+ 'MyEnum': {'enum': ['a', 'b'], 'type': 'string'},
860
876
  'MyRecursiveDc': {
861
- 'properties': {'field': {'anyOf': [{'$ref': '#/$defs/MyRecursiveDc'}, {'type': 'null'}]}},
877
+ 'properties': {
878
+ 'field': {'anyOf': [{'$ref': '#/$defs/MyRecursiveDc'}, {'type': 'null'}]},
879
+ 'my_enum': {'description': 'my enum', 'anyOf': [{'$ref': '#/$defs/MyEnum'}]},
880
+ },
862
881
  'type': 'object',
863
882
  'additionalProperties': False,
864
- 'required': ['field'],
883
+ 'required': ['field', 'my_enum'],
865
884
  },
866
885
  },
867
886
  'additionalProperties': False,
@@ -998,7 +1017,7 @@ def tool_with_tuples(x: tuple[int], y: tuple[str] = ('abc',)) -> str:
998
1017
  }
999
1018
  },
1000
1019
  'additionalProperties': False,
1001
- 'properties': {'x': {'oneOf': [{'type': 'integer'}, {'$ref': '#/$defs/MyDefaultDc'}]}},
1020
+ 'properties': {'x': {'anyOf': [{'type': 'integer'}, {'$ref': '#/$defs/MyDefaultDc'}]}},
1002
1021
  'required': ['x'],
1003
1022
  'type': 'object',
1004
1023
  }
@@ -1079,12 +1098,15 @@ def tool_with_tuples(x: tuple[int], y: tuple[str] = ('abc',)) -> str:
1079
1098
  {
1080
1099
  'additionalProperties': False,
1081
1100
  'properties': {
1082
- 'x': {'maxItems': 1, 'minItems': 1, 'prefixItems': [{'type': 'integer'}], 'type': 'array'},
1101
+ 'x': {
1102
+ 'prefixItems': [{'type': 'integer'}],
1103
+ 'type': 'array',
1104
+ 'description': 'minItems=1, maxItems=1',
1105
+ },
1083
1106
  'y': {
1084
- 'maxItems': 1,
1085
- 'minItems': 1,
1086
1107
  'prefixItems': [{'type': 'string'}],
1087
1108
  'type': 'array',
1109
+ 'description': 'minItems=1, maxItems=1',
1088
1110
  },
1089
1111
  },
1090
1112
  'required': ['x', 'y'],
@@ -1160,28 +1182,46 @@ def test_strict_schema():
1160
1182
  'MyModel': {
1161
1183
  'additionalProperties': False,
1162
1184
  'properties': {
1163
- 'my_discriminated_union': {'oneOf': [{'$ref': '#/$defs/Apple'}, {'$ref': '#/$defs/Banana'}]},
1185
+ 'my_discriminated_union': {'anyOf': [{'$ref': '#/$defs/Apple'}, {'$ref': '#/$defs/Banana'}]},
1164
1186
  'my_list': {'items': {'type': 'number'}, 'type': 'array'},
1165
1187
  'my_patterns': {
1166
1188
  'additionalProperties': False,
1167
- 'patternProperties': {'^my-pattern$': {'type': 'string'}},
1189
+ 'description': "patternProperties={'^my-pattern$': {'type': 'string'}}",
1168
1190
  'type': 'object',
1169
1191
  'properties': {},
1170
1192
  'required': [],
1171
1193
  },
1172
- 'my_recursive': {'anyOf': [{'$ref': '#/$defs/MyModel'}, {'type': 'null'}]},
1194
+ 'my_recursive': {'anyOf': [{'$ref': '#'}, {'type': 'null'}]},
1173
1195
  'my_tuple': {
1174
- 'maxItems': 1,
1175
- 'minItems': 1,
1176
1196
  'prefixItems': [{'type': 'integer'}],
1177
1197
  'type': 'array',
1198
+ 'description': 'minItems=1, maxItems=1',
1178
1199
  },
1179
1200
  },
1180
1201
  'required': ['my_recursive', 'my_patterns', 'my_tuple', 'my_list', 'my_discriminated_union'],
1181
1202
  'type': 'object',
1182
1203
  },
1183
1204
  },
1184
- '$ref': '#/$defs/MyModel',
1205
+ 'properties': {
1206
+ 'my_recursive': {'anyOf': [{'$ref': '#'}, {'type': 'null'}]},
1207
+ 'my_patterns': {
1208
+ 'type': 'object',
1209
+ 'description': "patternProperties={'^my-pattern$': {'type': 'string'}}",
1210
+ 'additionalProperties': False,
1211
+ 'properties': {},
1212
+ 'required': [],
1213
+ },
1214
+ 'my_tuple': {
1215
+ 'prefixItems': [{'type': 'integer'}],
1216
+ 'type': 'array',
1217
+ 'description': 'minItems=1, maxItems=1',
1218
+ },
1219
+ 'my_list': {'items': {'type': 'number'}, 'type': 'array'},
1220
+ 'my_discriminated_union': {'anyOf': [{'$ref': '#/$defs/Apple'}, {'$ref': '#/$defs/Banana'}]},
1221
+ },
1222
+ 'required': ['my_recursive', 'my_patterns', 'my_tuple', 'my_list', 'my_discriminated_union'],
1223
+ 'type': 'object',
1224
+ 'additionalProperties': False,
1185
1225
  }
1186
1226
  )
1187
1227
 
@@ -15,6 +15,7 @@ from pydantic_ai import Agent, ModelRetry, RunContext, UnexpectedModelBehavior,
15
15
  from pydantic_ai.messages import (
16
16
  BinaryContent,
17
17
  ModelMessage,
18
+ ModelMessagesTypeAdapter,
18
19
  ModelRequest,
19
20
  ModelResponse,
20
21
  ModelResponsePart,
@@ -1675,8 +1676,11 @@ def test_custom_output_type_invalid() -> None:
1675
1676
  def test_binary_content_all_messages_json():
1676
1677
  agent = Agent('test')
1677
1678
 
1678
- result = agent.run_sync(['Hello', BinaryContent(data=b'Hello', media_type='text/plain')])
1679
- assert json.loads(result.all_messages_json()) == snapshot(
1679
+ content = BinaryContent(data=b'Hello', media_type='text/plain')
1680
+ result = agent.run_sync(['Hello', content])
1681
+
1682
+ serialized = result.all_messages_json()
1683
+ assert json.loads(serialized) == snapshot(
1680
1684
  [
1681
1685
  {
1682
1686
  'parts': [
@@ -1698,6 +1702,10 @@ def test_binary_content_all_messages_json():
1698
1702
  ]
1699
1703
  )
1700
1704
 
1705
+ # We also need to be able to round trip the serialized messages.
1706
+ messages = ModelMessagesTypeAdapter.validate_json(serialized)
1707
+ assert messages == result.all_messages()
1708
+
1701
1709
 
1702
1710
  def test_instructions_raise_error_when_system_prompt_is_set():
1703
1711
  agent = Agent('test', instructions='An instructions!')
@@ -1805,3 +1813,59 @@ def test_instructions_with_message_history():
1805
1813
  ),
1806
1814
  ]
1807
1815
  )
1816
+
1817
+
1818
+ def test_empty_final_response():
1819
+ def llm(messages: list[ModelMessage], info: AgentInfo) -> ModelResponse:
1820
+ if len(messages) == 1:
1821
+ return ModelResponse(parts=[TextPart('foo'), ToolCallPart('my_tool', {'x': 1})])
1822
+ elif len(messages) == 3:
1823
+ return ModelResponse(parts=[TextPart('bar'), ToolCallPart('my_tool', {'x': 2})])
1824
+ else:
1825
+ return ModelResponse(parts=[])
1826
+
1827
+ agent = Agent(FunctionModel(llm))
1828
+
1829
+ @agent.tool_plain
1830
+ def my_tool(x: int) -> int:
1831
+ return x * 2
1832
+
1833
+ result = agent.run_sync('Hello')
1834
+ assert result.output == 'bar'
1835
+
1836
+ assert result.new_messages() == snapshot(
1837
+ [
1838
+ ModelRequest(parts=[UserPromptPart(content='Hello', timestamp=IsNow(tz=timezone.utc))]),
1839
+ ModelResponse(
1840
+ parts=[
1841
+ TextPart(content='foo'),
1842
+ ToolCallPart(tool_name='my_tool', args={'x': 1}, tool_call_id=IsStr()),
1843
+ ],
1844
+ model_name='function:llm:',
1845
+ timestamp=IsNow(tz=timezone.utc),
1846
+ ),
1847
+ ModelRequest(
1848
+ parts=[
1849
+ ToolReturnPart(
1850
+ tool_name='my_tool', content=2, tool_call_id=IsStr(), timestamp=IsNow(tz=timezone.utc)
1851
+ )
1852
+ ]
1853
+ ),
1854
+ ModelResponse(
1855
+ parts=[
1856
+ TextPart(content='bar'),
1857
+ ToolCallPart(tool_name='my_tool', args={'x': 2}, tool_call_id=IsStr()),
1858
+ ],
1859
+ model_name='function:llm:',
1860
+ timestamp=IsNow(tz=timezone.utc),
1861
+ ),
1862
+ ModelRequest(
1863
+ parts=[
1864
+ ToolReturnPart(
1865
+ tool_name='my_tool', content=4, tool_call_id=IsStr(), timestamp=IsNow(tz=timezone.utc)
1866
+ )
1867
+ ]
1868
+ ),
1869
+ ModelResponse(parts=[], model_name='function:llm:', timestamp=IsNow(tz=timezone.utc)),
1870
+ ]
1871
+ )
@@ -1,5 +1,7 @@
1
1
  """Tests for the MCP (Model Context Protocol) server implementation."""
2
2
 
3
+ from pathlib import Path
4
+
3
5
  import pytest
4
6
  from dirty_equals import IsInstance
5
7
  from inline_snapshot import snapshot
@@ -38,6 +40,14 @@ async def test_stdio_server():
38
40
  assert result.content == snapshot([TextContent(type='text', text='32.0')])
39
41
 
40
42
 
43
+ async def test_stdio_server_with_cwd():
44
+ test_dir = Path(__file__).parent
45
+ server = MCPServerStdio('python', ['mcp_server.py'], cwd=test_dir)
46
+ async with server:
47
+ tools = await server.list_tools()
48
+ assert len(tools) == 1
49
+
50
+
41
51
  def test_sse_server():
42
52
  sse_server = MCPServerHTTP(url='http://localhost:8000/sse')
43
53
  assert sse_server.url == 'http://localhost:8000/sse'
@@ -549,6 +549,20 @@ def test_init_plain_tool_invalid():
549
549
  Tool(ctx_tool, takes_ctx=False)
550
550
 
551
551
 
552
+ @pytest.mark.parametrize(
553
+ 'args, expected',
554
+ [
555
+ ('', {}),
556
+ ({'x': 42, 'y': 'value'}, {'x': 42, 'y': 'value'}),
557
+ ('{"a": 1, "b": "c"}', {'a': 1, 'b': 'c'}),
558
+ ],
559
+ )
560
+ def test_tool_call_part_args_as_dict(args: Union[str, dict[str, Any]], expected: dict[str, Any]):
561
+ part = ToolCallPart(tool_name='foo', args=args)
562
+ result = part.args_as_dict()
563
+ assert result == expected
564
+
565
+
552
566
  def test_return_pydantic_model():
553
567
  agent = Agent('test')
554
568
 
File without changes
File without changes
File without changes
File without changes