diff --git a/python/packages/core/agent_framework/_evaluation.py b/python/packages/core/agent_framework/_evaluation.py index 327258b846b..e7ffb79088d 100644 --- a/python/packages/core/agent_framework/_evaluation.py +++ b/python/packages/core/agent_framework/_evaluation.py @@ -1221,7 +1221,7 @@ def tool_call_args_match(item: EvalItem) -> CheckResult: for _, actual_args in matching: if actual_args is None: continue - if all(actual_args.get(k) == v for k, v in exp.arguments.items()): + if all(k in actual_args and actual_args[k] == v for k, v in exp.arguments.items()): found = True break diff --git a/python/packages/core/tests/core/test_local_eval.py b/python/packages/core/tests/core/test_local_eval.py index f3713506c22..e00e0d6a951 100644 --- a/python/packages/core/tests/core/test_local_eval.py +++ b/python/packages/core/tests/core/test_local_eval.py @@ -5,6 +5,7 @@ from __future__ import annotations import inspect +import json import pytest @@ -612,6 +613,37 @@ def test_args_mismatch(self): assert result.passed is False assert "args mismatch" in result.reason + @pytest.mark.parametrize("as_json", [False, True], ids=["dict", "json"]) + @pytest.mark.parametrize( + "arguments, expected_passed", + [ + pytest.param({"location": "NYC"}, False, id="missing"), + pytest.param({"location": "NYC", "units": None}, True, id="explicit-null"), + pytest.param({"location": "NYC", "units": "fahrenheit"}, False, id="non-null"), + pytest.param({"location": "NYC", "units": None, "days": 1}, True, id="extra-argument"), + ], + ) + def test_null_argument_requires_key(self, arguments, expected_passed, as_json): + item = EvalItem( + conversation=[ + Message( + "assistant", + [ + Content.from_function_call( + "call_weather", + "get_weather", + arguments=json.dumps(arguments) if as_json else arguments, + ) + ], + ) + ], + expected_tool_calls=[ExpectedToolCall("get_weather", {"location": "NYC", "units": None})], + ) + + result = tool_call_args_match(item) + + assert result.passed is expected_passed + def test_tool_not_called(self): item = _make_tool_call_item( calls=[("get_news", None)],