Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,15 @@ def _validate_response(self, response: Any) -> Optional[EvaluationException]:
"""Validate the response parameter."""
if response is None:
return EvaluationException(
message="'response' parameter is required and cannot be None.",
message="'actions' (also accepted as 'response') parameter is required and cannot be None.",
blame=ErrorBlame.USER_ERROR,
category=ErrorCategory.MISSING_FIELD,
target=self.error_target,
)

if not isinstance(response, list):
return EvaluationException(
message="'response' must be a list of messages.",
message="'actions' (also accepted as 'response') must be a list of messages.",
blame=ErrorBlame.USER_ERROR,
category=ErrorCategory.INVALID_VALUE,
target=self.error_target,
Expand Down Expand Up @@ -141,7 +141,7 @@ def _validate_ground_truth(self, ground_truth: Any) -> Optional[EvaluationExcept
"""Validate the ground_truth parameter."""
if not ground_truth:
return EvaluationException(
message="'ground_truth' parameter is required and cannot be None or empty.",
message="'expected_actions' (also accepted as 'ground_truth') parameter is required and cannot be None or empty.",
blame=ErrorBlame.USER_ERROR,
category=ErrorCategory.INVALID_VALUE,
target=self.error_target,
Expand All @@ -155,7 +155,7 @@ def _validate_ground_truth(self, ground_truth: Any) -> Optional[EvaluationExcept
# Validate tuple format: (list, dict)
if len(ground_truth) != 2:
return EvaluationException(
message="When 'ground_truth' is a tuple, it must contain exactly 2 elements: (tool_names_list, parameters_dict).",
message="When 'expected_actions' (also accepted as 'ground_truth') is a tuple, it must contain exactly 2 elements: (tool_names_list, parameters_dict).",
blame=ErrorBlame.USER_ERROR,
category=ErrorCategory.INVALID_VALUE,
target=self.error_target,
Expand All @@ -166,15 +166,15 @@ def _validate_ground_truth(self, ground_truth: Any) -> Optional[EvaluationExcept
# Validate tool names list
if not isinstance(tool_names, list):
return EvaluationException(
message="First element of 'ground_truth' tuple must be a list of tool names.",
message="First element of 'expected_actions' (also accepted as 'ground_truth') tuple must be a list of tool names.",
blame=ErrorBlame.USER_ERROR,
category=ErrorCategory.INVALID_VALUE,
target=self.error_target,
)

if len(tool_names) == 0:
return EvaluationException(
message="Tool names list in 'ground_truth' cannot be empty.",
message="Tool names list in 'expected_actions' (also accepted as 'ground_truth') cannot be empty.",
blame=ErrorBlame.USER_ERROR,
category=ErrorCategory.INVALID_VALUE,
target=self.error_target,
Expand All @@ -183,7 +183,7 @@ def _validate_ground_truth(self, ground_truth: Any) -> Optional[EvaluationExcept
for idx, name in enumerate(tool_names):
if not isinstance(name, str):
return EvaluationException(
message=f"Tool name at index {idx} in 'ground_truth' must be a string, got {type(name).__name__}.",
message=f"Tool name at index {idx} in 'expected_actions' (also accepted as 'ground_truth') must be a string, got {type(name).__name__}.",
blame=ErrorBlame.USER_ERROR,
category=ErrorCategory.INVALID_VALUE,
target=self.error_target,
Expand All @@ -192,7 +192,7 @@ def _validate_ground_truth(self, ground_truth: Any) -> Optional[EvaluationExcept
# Validate parameters dict
if not isinstance(parameters, dict):
return EvaluationException(
message="Second element of 'ground_truth' tuple must be a dictionary of parameters.",
message="Second element of 'expected_actions' (also accepted as 'ground_truth') tuple must be a dictionary of parameters.",
blame=ErrorBlame.USER_ERROR,
category=ErrorCategory.INVALID_VALUE,
target=self.error_target,
Expand All @@ -202,7 +202,7 @@ def _validate_ground_truth(self, ground_truth: Any) -> Optional[EvaluationExcept
for tool_name, params in parameters.items():
if not isinstance(params, dict):
return EvaluationException(
message=f"Parameters for tool '{tool_name}' in 'ground_truth' must be a dictionary, got {type(params).__name__}.",
message=f"Parameters for tool '{tool_name}' in 'expected_actions' (also accepted as 'ground_truth') must be a dictionary, got {type(params).__name__}.",
blame=ErrorBlame.USER_ERROR,
category=ErrorCategory.INVALID_VALUE,
target=self.error_target,
Expand All @@ -212,7 +212,7 @@ def _validate_ground_truth(self, ground_truth: Any) -> Optional[EvaluationExcept
# Validate list of tool names
if len(ground_truth) == 0:
return EvaluationException(
message="'ground_truth' list cannot be empty.",
message="'expected_actions' (also accepted as 'ground_truth') list cannot be empty.",
blame=ErrorBlame.USER_ERROR,
category=ErrorCategory.INVALID_VALUE,
target=self.error_target,
Expand All @@ -229,7 +229,7 @@ def _validate_ground_truth(self, ground_truth: Any) -> Optional[EvaluationExcept

else:
return EvaluationException(
message="'ground_truth' must be either a list of tool names or a tuple of (tool_names_list, parameters_dict).",
message="'expected_actions' (also accepted as 'ground_truth') must be either a list of tool names or a tuple of (tool_names_list, parameters_dict).",
blame=ErrorBlame.USER_ERROR,
category=ErrorCategory.INVALID_VALUE,
target=self.error_target,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,29 @@ def test_ground_truth_tuple_params_not_dict_raises(self):
with pytest.raises(EvaluationException):
validator.validate_eval_input(eval_input)

@pytest.mark.parametrize(
"eval_input, canonical_name, alias_name",
[
# 'response'/'actions' missing (None).
({"response": None, "ground_truth": ["search"]}, "response", "actions"),
# 'response'/'actions' wrong type.
({"response": "not a list", "ground_truth": ["search"]}, "response", "actions"),
# 'ground_truth'/'expected_actions' empty -- the reported UX case.
({"response": [{"role": "user", "content": "x"}], "ground_truth": []}, "ground_truth", "expected_actions"),
# 'ground_truth'/'expected_actions' wrong type.
({"response": [{"role": "user", "content": "x"}], "ground_truth": 123}, "ground_truth", "expected_actions"),
],
)
def test_error_messages_name_both_canonical_and_alias(self, eval_input, canonical_name, alias_name):
# Regression guard: user-facing validation errors must cite both the SDK input name and
# its azureml-assets alias, so a caller never sees a parameter name they did not supply.
validator = TaskNavigationEfficiencyValidator(error_target=TARGET)
with pytest.raises(EvaluationException) as exc_info:
validator.validate_eval_input(eval_input)
message = str(exc_info.value)
assert f"'{canonical_name}'" in message
assert f"'{alias_name}'" in message


@pytest.mark.unittest
class TestMessagesOrQueryResponseInputValidator:
Expand Down
Loading