From 5b1edaac9ce680879cec615280a149ea50374b76 Mon Sep 17 00:00:00 2001 From: Ahmad Ragab Date: Wed, 8 Apr 2026 17:15:52 -0400 Subject: [PATCH] fix: make _EvalMetricResultWithInvocation.expected_invocation Optional When using conversation_scenario for user simulation, expected_invocation is None because conversations are dynamically generated. The public model EvalMetricResultPerInvocation already types this as Optional[Invocation], but the private _EvalMetricResultWithInvocation requires non-None, causing a pydantic ValidationError during post-processing. - Make expected_invocation Optional[Invocation] = None - Guard attribute accesses in _print_details to handle None - Fall back to actual_invocation.user_content for the prompt column Fixes #5214 --- src/google/adk/evaluation/agent_evaluator.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/google/adk/evaluation/agent_evaluator.py b/src/google/adk/evaluation/agent_evaluator.py index c0fc736340..8306f1b75b 100644 --- a/src/google/adk/evaluation/agent_evaluator.py +++ b/src/google/adk/evaluation/agent_evaluator.py @@ -90,7 +90,7 @@ class _EvalMetricResultWithInvocation(BaseModel): """ actual_invocation: Invocation - expected_invocation: Invocation + expected_invocation: Optional[Invocation] = None eval_metric_result: EvalMetricResult @@ -438,15 +438,21 @@ def _print_details( "threshold": threshold, "prompt": AgentEvaluator._convert_content_to_text( per_invocation_result.expected_invocation.user_content + if per_invocation_result.expected_invocation + else per_invocation_result.actual_invocation.user_content ), "expected_response": AgentEvaluator._convert_content_to_text( per_invocation_result.expected_invocation.final_response + if per_invocation_result.expected_invocation + else None ), "actual_response": AgentEvaluator._convert_content_to_text( per_invocation_result.actual_invocation.final_response ), "expected_tool_calls": AgentEvaluator._convert_tool_calls_to_text( per_invocation_result.expected_invocation.intermediate_data + if per_invocation_result.expected_invocation + else None ), "actual_tool_calls": AgentEvaluator._convert_tool_calls_to_text( per_invocation_result.actual_invocation.intermediate_data