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