From f2ec56103128daf05bc9f148d7cbf53a72b3be40 Mon Sep 17 00:00:00 2001 From: Calin Teodor <45018530+TeoSlayer@users.noreply.github.com> Date: Wed, 28 Oct 2026 09:01:44 -0700 Subject: [PATCH 1/2] fix: reject calls without declared tools --- src/inference_endpoint/evaluation/bfcl_v4_execution.py | 2 +- tests/unit/evaluation/test_bfcl_v4_execution.py | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/inference_endpoint/evaluation/bfcl_v4_execution.py b/src/inference_endpoint/evaluation/bfcl_v4_execution.py index e6b51293c..d7d57e228 100644 --- a/src/inference_endpoint/evaluation/bfcl_v4_execution.py +++ b/src/inference_endpoint/evaluation/bfcl_v4_execution.py @@ -231,7 +231,7 @@ def process_response( model_responses_bfcl = [] for tc in tool_calls: name = tc["name"] - if allowed_names and name not in allowed_names: + if name not in allowed_names: logger.warning( "Dropping tool call to undeclared function %r for %s turn " "%d (not in the entry's tool list); refusing to execute an " diff --git a/tests/unit/evaluation/test_bfcl_v4_execution.py b/tests/unit/evaluation/test_bfcl_v4_execution.py index 86856adc3..b0bbf0941 100644 --- a/tests/unit/evaluation/test_bfcl_v4_execution.py +++ b/tests/unit/evaluation/test_bfcl_v4_execution.py @@ -40,7 +40,7 @@ def _state(entry_id="multi_turn_base_0", max_steps=25): current_step=0, current_turn_results=[], messages=[], - tools=[], + tools=[{"type": "function", "function": {"name": "f"}}], force_terminated=False, completed=False, model_results_per_turn=[], @@ -112,14 +112,18 @@ def test_process_response_no_tool_calls_advances_turn(): @pytest.mark.unit -def test_process_response_drops_undeclared_tool_name(): +@pytest.mark.parametrize( + "tools", + [[{"type": "function", "function": {"name": "f"}}], [], [{"type": "function"}]], +) +def test_process_response_drops_undeclared_tool_name(tools): """A tool call to a name the entry never declared must not reach bfcl-eval's executor (guards against injection like __import__('os').system).""" executed = [] bridge = _make_bridge() state = _state() state.entry.num_turns = 1 - state.tools = [{"type": "function", "function": {"name": "f"}}] + state.tools = tools with ( patch.object(ex, "convert_to_function_call", lambda calls: list(calls)), patch.object(ex, "is_empty_execute_response", lambda d: len(d) == 0), From 2fd9015710b8d3971b896b0f46bd445dff817151 Mon Sep 17 00:00:00 2001 From: Calin Teodor <45018530+TeoSlayer@users.noreply.github.com> Date: Thu, 5 Nov 2026 09:38:59 -0800 Subject: [PATCH 2/2] test: wait for benchmark startup before wedging metrics --- tests/integration/commands/test_sigint.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tests/integration/commands/test_sigint.py b/tests/integration/commands/test_sigint.py index 1197744dc..d6986981e 100644 --- a/tests/integration/commands/test_sigint.py +++ b/tests/integration/commands/test_sigint.py @@ -276,6 +276,7 @@ def test_sigint_grace_expiry_abandons_wedged_drain(mock_http_echo_server, tmp_pa """ report_dir = tmp_path / "report" config_path = tmp_path / "bench.yaml" + log_file = tmp_path / "run.log" _write_config( report_dir, mock_http_echo_server.url, @@ -286,10 +287,18 @@ def test_sigint_grace_expiry_abandons_wedged_drain(mock_http_echo_server, tmp_pa agg_pid: int | None = None try: with _benchmark_proc( - [_cli(), "benchmark", "from-config", "-c", str(config_path)] + [_cli(), "benchmark", "from-config", "-c", str(config_path)], + log_file, ) as proc: _wait_services_ready(proc, report_dir) - time.sleep(3.0) # comfortably inside the ~120 s performance phase + # Service readiness precedes client startup. Wait for the session + # before allowing live metrics ticks to reach the parent. + deadline = time.monotonic() + 60.0 + while "Starting phase:" not in log_file.read_text(errors="replace"): + assert proc.poll() is None, log_file.read_text(errors="replace") + assert time.monotonic() < deadline, "performance phase never started" + time.sleep(0.05) + time.sleep(3.0) agg_pid = _pid_of_child("metrics_aggregator", str(report_dir)) assert agg_pid is not None, "aggregator child not found"