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